diff --git a/Backend/backend.iml b/Backend/backend.iml index 602a7c5606322fb071b3ddf29b4a5a9609cfd61c..0e6539c19b714a0f8a2f019f22e8cf7c406d50db 100644 --- a/Backend/backend.iml +++ b/Backend/backend.iml @@ -1,6 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> <component name="FacetManager"> + <facet type="jpa" name="JPA"> + <configuration> + <setting name="validation-enabled" value="true" /> + <setting name="provider-name" value="Hibernate" /> + <datasource-mapping /> + <naming-strategy-map /> + </configuration> + </facet> <facet type="Spring" name="Spring"> <configuration /> </facet> @@ -13,16 +21,6 @@ </sourceRoots> </configuration> </facet> - <facet type="jpa" name="JPA"> - <configuration> - <setting name="validation-enabled" value="true" /> - <setting name="provider-name" value="Hibernate" /> - <datasource-mapping> - <factory-entry name="entityManagerFactory" value="0e22f7ab-8d99-4909-a492-88107b731cf0" /> - </datasource-mapping> - <naming-strategy-map /> - </configuration> - </facet> </component> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_11"> <output url="file://$MODULE_DIR$/target/classes" /> diff --git a/Backend/src/main/java/com/ebdapo/backend/restcontroller/BenutzerController.java b/Backend/src/main/java/com/ebdapo/backend/restcontroller/BenutzerController.java index 4303ed3758927376e09a3434eea3f81b703441d9..a4f5096c024b8215b5bf6047ee2f548964055a6b 100644 --- a/Backend/src/main/java/com/ebdapo/backend/restcontroller/BenutzerController.java +++ b/Backend/src/main/java/com/ebdapo/backend/restcontroller/BenutzerController.java @@ -179,8 +179,8 @@ public class BenutzerController { return new ResponseEntity<>(HttpStatus.OK); } - @PostMapping("/apotheke/{apothekeId}/benutzer/{username}/checkUsername") - public ResponseEntity<?> checkIfUsernameTagenUsername(@PathVariable String apothekeId, @PathVariable String username) { + @PostMapping("/benutzer/{username}/checkUsername") + public ResponseEntity<?> checkIfUsernameTagenUsername(@PathVariable String username) { if (username.length() >= 4 && benutzerRepo.getBenutzerByUsername(username) == null) { return new ResponseEntity<>(HttpStatus.OK); diff --git a/Backend/src/main/java/com/ebdapo/backend/restcontroller/BetaeubungsmittelBuchungController.java b/Backend/src/main/java/com/ebdapo/backend/restcontroller/BetaeubungsmittelBuchungController.java index 2c29376f4c0130384f609d5cfdcdcc559963577a..a1d39234e8cacedd2772cd0437d8ec1466487289 100644 --- a/Backend/src/main/java/com/ebdapo/backend/restcontroller/BetaeubungsmittelBuchungController.java +++ b/Backend/src/main/java/com/ebdapo/backend/restcontroller/BetaeubungsmittelBuchungController.java @@ -238,6 +238,7 @@ public class BetaeubungsmittelBuchungController { //Wenn eine Buchung aktualisiert wird, muss die vorherige Mengenberechnung //rückgängig gemacht werden btm.setMenge(btm.getMenge()-previousMenge+newBtmBuchung.getMenge()); + z.setDatum(newBtmBuchung.getDatum()); z.setBenutzer(benutzerRepository.findById(newBtmBuchung.getBenutzer()).orElseThrow(InvalidInputException::new)); z.setBtm(btmRepo.findById(newBtmBuchung.getBtm()).orElseThrow(InvalidInputException::new)); z.setMenge(newBtmBuchung.getMenge()); @@ -256,6 +257,7 @@ public class BetaeubungsmittelBuchungController { int previousMenge = a.getMenge(); if(!pruefer){ btm.setMenge(btm.getMenge()+previousMenge-newBtmBuchung.getMenge()); + a.setDatum(newBtmBuchung.getDatum()); a.setBenutzer(benutzerRepository.findById(newBtmBuchung.getBenutzer()).orElseThrow(InvalidInputException::new)); a.setBtm(btmRepo.findById(newBtmBuchung.getBtm()).orElseThrow(InvalidInputException::new)); a.setMenge(newBtmBuchung.getMenge()); diff --git a/Backend/src/main/java/com/ebdapo/backend/security/SecurityConfiguration.java b/Backend/src/main/java/com/ebdapo/backend/security/SecurityConfiguration.java index e94624ce3148b48f51e902df2baa8464294afa37..253ab0d43b060ab574a3789b226184451e321774 100644 --- a/Backend/src/main/java/com/ebdapo/backend/security/SecurityConfiguration.java +++ b/Backend/src/main/java/com/ebdapo/backend/security/SecurityConfiguration.java @@ -34,6 +34,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter implemen @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() + .antMatchers(HttpMethod.POST, "/benutzer/*/checkUsername").permitAll() .antMatchers(HttpMethod.GET, "/apotheke/**").hasAnyRole("BENUTZER", "ADMIN", "PRUEFER") .antMatchers(HttpMethod.DELETE, "/**").hasAnyRole("ADMIN") .antMatchers(HttpMethod.PUT, "​/apotheke​/*​/btmbuchung​/*").hasAnyRole("PRUEFER","ADMIN") diff --git a/frontend/src/App.scss b/frontend/src/App.scss index 3addce4ad8f470dfe3c73a03dc540d417837f1c0..6393da7d05a9d6531e137cc968d8ea3604fcc4b6 100644 --- a/frontend/src/App.scss +++ b/frontend/src/App.scss @@ -63,3 +63,15 @@ $theme-colors: ( border: $base-green-2 !important; } +.unselectable { + pointer-events: none; + /* For Opera and <= IE9, we need to add unselectable="on" attribute onto each element */ + /* Check this site for more details: http://help.dottoro.com/lhwdpnva.php */ + -moz-user-select: none; /* These user-select properties are inheritable, used to prevent text selection */ + -webkit-user-select: none; + -ms-user-select: none; /* From IE10 only */ + user-select: none; /* Not valid CSS yet, as of July 2012 */ + + -webkit-user-drag: none; /* Prevents dragging of images/divs etc */ + user-drag: none; +} \ No newline at end of file diff --git a/frontend/src/components/btmbuch/BuchungTabelle.js b/frontend/src/components/btmbuch/BuchungTabelle.js index 17bd3dd2846ae594e62216093ba299ceddec031b..ee5a50b47fd6dae8b2d0c27692faf563699d56bc 100644 --- a/frontend/src/components/btmbuch/BuchungTabelle.js +++ b/frontend/src/components/btmbuch/BuchungTabelle.js @@ -7,7 +7,7 @@ import Moment from "react-moment"; import { useSnackbar } from "notistack"; import { useParams } from "react-router-dom"; import TableBody from '@material-ui/core/TableBody'; -import NeueBuchungModal from "./NeueBuchungModal"; +import NeueBuchungModal from "../../modals/NeueBuchungModal"; import UpdateBuchungModal from "../../modals/UpdateBuchungModal"; import DeleteModal from "../../modals/DeleteModal"; import PrintPdfModal from "../../modals/PrintPdfModal" @@ -206,9 +206,6 @@ function BuchungTabelle(props) { } }; - const testeStartDate = () => { - console.log("start Date" , startDate, " ", endDate) - } const exportPdf = () => { const unit = "pt"; @@ -223,7 +220,7 @@ function BuchungTabelle(props) { const moment = require('moment'); - const filteredData = btm.buchungen.filter((d) => d.datum >= moment(startDate).format("YYYY-MM-DD") && d.datum <= moment(endDate).format("YYYY-MM-DD")); //<= moment(endDate).format("YYYY-MM-DD")); + const filteredData = btm.buchungen.filter((d) => d.datum >= moment(startDate).format("YYYY-MM-DD") && d.datum <= moment(endDate).format("YYYY-MM-DD")); const data = filteredData.map(buchung => [moment(buchung.datum).format("DD.MM.YYYY"), buchung.typ === "ZUGANG" ? buchung.lieferant.name + "\n" + buchung.lieferant.anschrift.strasse + " " + buchung.lieferant.anschrift.nummer + ",\n"+ buchung.lieferant.anschrift.ort +" " + buchung.lieferant.anschrift.plz : buchung.empfaenger.vorname + " " + buchung.empfaenger.name + "\n" + buchung.empfaenger.anschrift.strasse +" "+ buchung.empfaenger.anschrift.nummer + ",\n" + buchung.empfaenger.anschrift.ort + ",\n" + buchung.empfaenger.anschrift.plz , diff --git a/frontend/src/components/startseite/Startseite.js b/frontend/src/components/startseite/Startseite.js index 26b977206cd124de9d2ad51559feabae4d076703..5d015eae9fbb9dc4c5d327fe559ff9cf48a92a7c 100644 --- a/frontend/src/components/startseite/Startseite.js +++ b/frontend/src/components/startseite/Startseite.js @@ -15,7 +15,7 @@ function Startseite(props) { showLoginForm={showLoginForm} setShowLoginForm={setShowLoginForm} showLoginButton={true} /> <div className="banner"> - <img className="bg-image" src="/images/background/bg1.svg" alt="" /> + <img className="bg-image unselectable" src="/images/background/bg1.svg" alt="" /> <div style={{position:'absolute', margin:'0 10%', top:'0'}}> <Row> @@ -28,7 +28,7 @@ function Startseite(props) { </Row> </Col> <Col> - <img className="img" style={{marginTop:'5%'}} className="float-right" src="/images/pharma1.png" /> + <img className="img unselectable float-right" style={{marginTop:'5%'}} src="/images/pharma1.png" /> </Col> </Row> <Row style={{marginTop:'13em'}}> @@ -53,15 +53,15 @@ function Startseite(props) { </ul> </Col> <Col> - <img className="img" style={{marginTop:'-5em'}} className="float-right" src="/images/pharma2.png" /> + <img className="img unselectable" style={{marginTop:'-5em'}} src="/images/pharma2.png" /> </Col> </Row> </div> - <img className="bg-image" style={{marginTop:'20em'}} src="/images/background/bg2.svg" alt="" /> + <img className="bg-image unselectable" style={{marginTop:'20em'}} src="/images/background/bg2.svg" alt="" /> <div style={{backgroundColor:'#0e864e', paddingBottom:'4em'}}> <Row> <Col> - <img className="img" style={{margin:'-11em 0 0 5em'}} className="float-left" src="/images/akteure.png" /> + <img className="img unselectable float-left" style={{margin:'-11em 0 0 5em'}} src="/images/akteure.png" /> </Col> <Col style={{color:'white'}}> <h3> diff --git a/frontend/src/components/startseite/Startseite.scss b/frontend/src/components/startseite/Startseite.scss index 3414ae79dd95aa27311cca1466d36b85d0f639e1..f9e9fdf4b4ab1c3b4c7c4110fa59f4d233a928f3 100644 --- a/frontend/src/components/startseite/Startseite.scss +++ b/frontend/src/components/startseite/Startseite.scss @@ -38,7 +38,6 @@ p, li { .img { height: auto; width: auto; - } diff --git a/frontend/src/modals/ApothekeRegisterModal.js b/frontend/src/modals/ApothekeRegisterModal.js index 1bf4b3037015cbaf632507f82857a0aecf22d841..c949f61c10723870b153e9a88802ea6f2508e4f9 100644 --- a/frontend/src/modals/ApothekeRegisterModal.js +++ b/frontend/src/modals/ApothekeRegisterModal.js @@ -4,12 +4,12 @@ import { useForm } from "./useForm"; function ApothekeRegisterModal(props) { - const [disabled, setDisabled] = useState(true); - const [disabledRegBt, setDisabledRegBt] = useState(true); + const [step1WeiterButtonDisabled, setStep1WeiterButtonDisabled] = useState(true); const [fields, setFields] = useState({name: "", email: "", strasse: "",nummer: "", plz: "", ort: "" }); const [passwords, setPasswords] = useState({password: "", passwordCheck: ""}); const [showContinueModal, setShowContinueModal] = useState(false); - const [passwordsAreValid, setPasswordsAreValid] = useState(''); + const [passwordsAreValid, setPasswordsAreValid] = useState(false); + const [usernameTaken, setUsernameTaken] = useState(true); const [values, handleChangeCustom] = useForm({ vorname: "", @@ -28,16 +28,17 @@ function ApothekeRegisterModal(props) { const checkPlzOrt = () => { if(fields.plz.match('[0-9]{5}') && fields.plz.length === 5 && fields.ort.length >= 2) { - setDisabled(false); + setStep1WeiterButtonDisabled(false); } else{ - setDisabled(true); + setStep1WeiterButtonDisabled(true); } } const validation = () => { checkPlzOrt(); checkPasswords(); + checkUsernameTaken(); } const handleBack = () => { @@ -115,13 +116,12 @@ function ApothekeRegisterModal(props) { } - const checkPasswords = () => { - if (passwords.password.toString() !== '' && passwords.password.toString() === passwords.passwordCheck.toString()) { + const checkPasswords = () => { + let pw = passwords.password; + let check = passwords.passwordCheck; + if (pw !== '' && pw.length >= 5 && pw === check) { setPasswordsAreValid(true); - setDisabledRegBt(false); - } - else { - setDisabledRegBt(true); + }else { setPasswordsAreValid(false); } } @@ -148,8 +148,24 @@ function ApothekeRegisterModal(props) { } }; + const checkUsernameTaken = async () => { + if(values.nutzername){ + await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/benutzer/${values.nutzername}/checkUsername`, { + method: 'POST', + }).then((res) => { + if (res.status === 200) { + setUsernameTaken(false); + } else if (res.status === 400) { + setUsernameTaken(true); + } + }).catch((err) => { + console.log(err); + setUsernameTaken(true); + }); + } + } + useEffect(() => { - document.title = `${passwords.password} , ${passwords.passwordCheck} , ${disabledRegBt}, ${fields}, ${passwordsAreValid} `; validation(); }) @@ -283,7 +299,7 @@ function ApothekeRegisterModal(props) { name="nutzername" value={values.nutzername} onChange={handleChangeCustom} - isValid={values.nutzername.match("[A-Za-z]{1,32}")} + isValid={values.nutzername.match("[A-Za-z]{1,32}") && !usernameTaken} /> </Form.Group> <Form.Group controlId="password"> @@ -316,13 +332,13 @@ function ApothekeRegisterModal(props) { const renderWeiterBt = () => { return ( - <Button disabled={disabled} onClick={() => setShowContinueModal(true)}>Weiter</Button> + <Button disabled={step1WeiterButtonDisabled} onClick={() => setShowContinueModal(true)}>Weiter</Button> ) } const renderRegistrierenBt = () => { return( - <Button disabled={disabledRegBt ? true : false} type="submit" >Registrieren</Button> + <Button disabled={!(!usernameTaken && passwordsAreValid)} type="submit" >Registrieren</Button> ) } diff --git a/frontend/src/modals/BtmAddModal.js b/frontend/src/modals/BtmAddModal.js index af1e308ed88289a6dded35e5388e7defebbb56aa..7fb5121b21fcef7733c0b1458b152cc0686fb542 100644 --- a/frontend/src/modals/BtmAddModal.js +++ b/frontend/src/modals/BtmAddModal.js @@ -41,12 +41,26 @@ function BtmAddModal(props) { ); setShowError(true); } - }) - .catch((err) => { - //SHOW ERROR - console.log(err); - }); - }; + }).then((res) => { + if (res.status === 201) { + console.log(props); + let {updateBtmList} = props.apothekeRefFunctions; + updateBtmList(); + props.onHide(); + setShowError(false); + enqueueSnackbar('Betäubungsmittel erfolgreich angelegt', { variant: 'success', autoHideDuration: 3000 }); + } else if (res.status === 400) { + setErrorMessage('Betäubungsmittel existiert bereits oder Daten ungültig'); + setShowError(true); + } + }).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + + + } // let einheiten = ['g','mg','ml', 'Stueck'] let darreichungsformen = { diff --git a/frontend/src/components/btmbuch/NeueBuchungModal.js b/frontend/src/modals/NeueBuchungModal.js similarity index 96% rename from frontend/src/components/btmbuch/NeueBuchungModal.js rename to frontend/src/modals/NeueBuchungModal.js index 1db6d2371e39f6c91924ddd09e040a9c69d494c8..d55a43101aa6f35c025d09e175285c6f4b809e4e 100644 --- a/frontend/src/components/btmbuch/NeueBuchungModal.js +++ b/frontend/src/modals/NeueBuchungModal.js @@ -1,207 +1,210 @@ -import React, { useState, useEffect } from 'react'; -import { Modal, Button, Form, Row, Col } from 'react-bootstrap'; -import { useSnackbar } from 'notistack'; - -function NeueBuchungModal(props) { - - const { enqueueSnackbar } = useSnackbar(); - const [typ, setTyp] = useState(''); - let {lieferanten, aerzte, empfaenger} = props; - - - const [maxMenge, setMaxMenge] = useState(props.btm.btm.menge); - - const sendNewBuchungAnfrage = async (buchungData) => { - const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${props.apothekeId}/btmbuchung`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + window.sessionStorage.getItem("edbapo-jwt"), - }, - body: JSON.stringify(buchungData) - }).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - - if (response && response.status === 201) { - //const data = await response.json(); - // console.log(data); - hideModal(); - enqueueSnackbar('Buchung erfolgreich angelegt', { variant:'success', autoHideDuration: 3000} ); - props.apothekeRefFunctions.updateBtmList(); - } else { - //SHOW ERROR - console.log(response); - } - } - - const createNewBuchung = event => { - event.preventDefault(); - if (typ.toLowerCase() === 'zugang') { - let { anforderungsschein, btmMenge, lieferant, datum} = event.target; - let buchungData = { - benutzer: props.user.id, - btm: props.btm.btm.id, - menge: btmMenge.value, - typ: 'ZUGANG', - lieferant: lieferant.value, - anforderungsschein: anforderungsschein.value, - datum: datum.value, - pruefdatum: '' - } - sendNewBuchungAnfrage(buchungData); - } else if (typ.toLowerCase() === 'abgang') { - let { btmMenge, rezept, empfaenger, arzt, datum} = event.target; - let buchungData = { - benutzer: props.user.id, - btm: props.btm.btm.id, - menge: btmMenge.value, - typ: 'ABGANG', - empfaenger: empfaenger.value, - arzt: arzt.value, - rezept: rezept.value, - pruefdatum: '', - datum: datum.value - } - sendNewBuchungAnfrage(buchungData); - } - } - - const hideModal = () => { - setTyp(''); - props.onHide(); - } - - useEffect(() => { - setMaxMenge(props.btm.btm.menge) - }, [props.btm.btm.menge]); - - const renderZugang = () => { - return ( - <React.Fragment> - <Form.Group as={Row} controlId="anforderungsschein"> - <Form.Label column sm="2"> - Lieferschein - </Form.Label> - <Col sm="10"> - <Form.Control name="anforderungsschein" type="text" required /> - </Col> - </Form.Group> - <Form.Group as={Row} controlId="lieferant"> - <Form.Label column sm="2"> - Lieferant - </Form.Label> - <Col sm="10"> - <Form.Control name="lieferant" required as="select"> - {lieferanten.map(l => <option key={l.id} value={l.id}>{l.name}</option>)} - </Form.Control> - </Col> - </Form.Group> - </React.Fragment>) - } - - const renderAbgang = () => { - return ( - <React.Fragment> - <Form.Group as={Row} controlId="empfaenger"> - <Form.Label column sm="2"> - Empfaenger - </Form.Label> - <Col sm="10"> - <Form.Control name="empfaenger" required as="select"> - {empfaenger.map(e => <option key={e.id} value={e.id}>{e.name}</option>)} - </Form.Control> - </Col> - </Form.Group> - <Form.Group as={Row} controlId="arzt"> - <Form.Label column sm="2"> - Arzt - </Form.Label> - <Col sm="10"> - <Form.Control name="arzt" required as="select"> - {aerzte.map(a => <option key={a.id} value={a.id}>{a.name}</option>)} - </Form.Control> - </Col> - </Form.Group> - <Form.Group as={Row} controlId="rezept"> - <Form.Label column sm="2"> - Rezept - </Form.Label> - <Col sm="10"> - <Form.Control name="rezept" type="text" required /> - </Col> - </Form.Group> - </React.Fragment>) - } - - return ( - <Modal - {...props} - size="lg" - aria-labelledby="contained-modal-title-vcenter" - centered - onExiting={hideModal} - backdrop="static" - > - <Modal.Header closeButton> - <Modal.Title id="contained-modal-title-vcenter"> - Betäubungsmittel-Buchung hinzufügen - </Modal.Title> - </Modal.Header> - <Form onSubmit={createNewBuchung}> - <Modal.Body> - <Form.Group as={Row} controlId="Typ"> - <Col sm={{ span: 10, offset: 2 }}> - <Row sm={6}> - <Form.Check required - type="radio" - label="Zugang" - name="TypRadio" - id="ZugangRadio" - onClick={() => {setTyp('zugang'); setMaxMenge(9999)}} - /> - <Form.Check required - type="radio" - label="Abgang" - name="TypRadio" - id="AbgangRadio" - onClick={() => {setTyp('abgang'); setMaxMenge(props.btm.btm.menge)}} - /> - </Row> - </Col> - </Form.Group> - - <Form.Group as={Row} controlId="btmMenge"> - <Form.Label column sm="2"> - Menge - </Form.Label> - <Col sm="10"> - <Form.Control name="btmMenge" type="number" min="1" max={maxMenge} defaultValue="0" /> - </Col> - </Form.Group> - <Form.Group as={Row} controlId="datum"> - <Form.Label column sm="2"> - Datum - </Form.Label> - <Col sm="10"> - <Form.Control name="datum" type="date" defaultValue={new Date()} /> - </Col> - </Form.Group> - - {typ.toLowerCase() === 'zugang' ? renderZugang() : null} - {typ.toLowerCase() === 'abgang' ? renderAbgang() : null} - - </Modal.Body> - <Modal.Footer> - <Button variant="danger" onClick={hideModal}>Abbrechen</Button> - <Button variant="primary" type="submit">Bestätigen</Button> - </Modal.Footer> - </Form> - </Modal> - ) -} - -export default NeueBuchungModal; - +import React, { useState, useEffect } from 'react'; +import { Modal, Button, Form, Row, Col } from 'react-bootstrap'; +import { useSnackbar } from 'notistack'; + +function NeueBuchungModal(props) { + + const moment = require('moment'); + const { enqueueSnackbar } = useSnackbar(); + const [typ, setTyp] = useState(''); + let {lieferanten, aerzte, empfaenger} = props; + + const [date, setDate] = useState(moment(new Date).format("YYYY-MM-DD")); + + const [maxMenge, setMaxMenge] = useState(props.btm.btm.menge); + + const sendNewBuchungAnfrage = async (buchungData) => { + const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${props.apothekeId}/btmbuchung`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + window.sessionStorage.getItem("edbapo-jwt"), + }, + body: JSON.stringify(buchungData) + }).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + + if (response && response.status === 201) { + //const data = await response.json(); + // console.log(data); + hideModal(); + enqueueSnackbar('Buchung erfolgreich angelegt', { variant:'success', autoHideDuration: 3000} ); + props.apothekeRefFunctions.updateBtmList(); + } else { + //SHOW ERROR + console.log(response); + } + } + + const createNewBuchung = event => { + event.preventDefault(); + if (typ.toLowerCase() === 'zugang') { + let { anforderungsschein, btmMenge, lieferant, datum} = event.target; + let buchungData = { + benutzer: props.user.id, + btm: props.btm.btm.id, + menge: btmMenge.value, + typ: 'ZUGANG', + lieferant: lieferant.value, + anforderungsschein: anforderungsschein.value, + datum: datum.value, + pruefdatum: '' + } + sendNewBuchungAnfrage(buchungData); + } else if (typ.toLowerCase() === 'abgang') { + let { btmMenge, rezept, empfaenger, arzt, datum} = event.target; + let buchungData = { + benutzer: props.user.id, + btm: props.btm.btm.id, + menge: btmMenge.value, + typ: 'ABGANG', + empfaenger: empfaenger.value, + arzt: arzt.value, + rezept: rezept.value, + pruefdatum: '', + datum: datum.value + } + sendNewBuchungAnfrage(buchungData); + } + } + + const hideModal = () => { + setTyp(''); + setDate(moment(new Date).format("YYYY-MM-DD")); + props.onHide(); + } + + useEffect(() => { + setMaxMenge(props.btm.btm.menge) + }, [props.btm.btm.menge]); + + const renderZugang = () => { + return ( + <React.Fragment> + <Form.Group as={Row} controlId="anforderungsschein"> + <Form.Label column sm="2"> + Lieferschein + </Form.Label> + <Col sm="10"> + <Form.Control name="anforderungsschein" type="text" required /> + </Col> + </Form.Group> + <Form.Group as={Row} controlId="lieferant"> + <Form.Label column sm="2"> + Lieferant + </Form.Label> + <Col sm="10"> + <Form.Control name="lieferant" required as="select"> + {lieferanten.map(l => <option key={l.id} value={l.id}>{l.name}</option>)} + </Form.Control> + </Col> + </Form.Group> + </React.Fragment>) + } + + const renderAbgang = () => { + return ( + <React.Fragment> + <Form.Group as={Row} controlId="empfaenger"> + <Form.Label column sm="2"> + Empfaenger + </Form.Label> + <Col sm="10"> + <Form.Control name="empfaenger" required as="select"> + {empfaenger.map(e => <option key={e.id} value={e.id}>{e.name}</option>)} + </Form.Control> + </Col> + </Form.Group> + <Form.Group as={Row} controlId="arzt"> + <Form.Label column sm="2"> + Arzt + </Form.Label> + <Col sm="10"> + <Form.Control name="arzt" required as="select"> + {aerzte.map(a => <option key={a.id} value={a.id}>{a.name}</option>)} + </Form.Control> + </Col> + </Form.Group> + <Form.Group as={Row} controlId="rezept"> + <Form.Label column sm="2"> + Rezept + </Form.Label> + <Col sm="10"> + <Form.Control name="rezept" type="text" required /> + </Col> + </Form.Group> + </React.Fragment>) + } + + return ( + <Modal + {...props} + size="lg" + aria-labelledby="contained-modal-title-vcenter" + centered + onExiting={hideModal} + backdrop="static" + > + <Modal.Header closeButton> + <Modal.Title id="contained-modal-title-vcenter"> + Betäubungsmittel-Buchung hinzufügen + </Modal.Title> + </Modal.Header> + <Form onSubmit={createNewBuchung}> + <Modal.Body> + <Form.Group as={Row} controlId="Typ"> + <Col sm={{ span: 10, offset: 2 }}> + <Row sm={6}> + <Form.Check required + type="radio" + label="Zugang" + name="TypRadio" + id="ZugangRadio" + onClick={() => {setTyp('zugang'); setMaxMenge(9999)}} + /> + <Form.Check required + type="radio" + label="Abgang" + name="TypRadio" + id="AbgangRadio" + onClick={() => {setTyp('abgang'); setMaxMenge(props.btm.btm.menge)}} + /> + </Row> + </Col> + </Form.Group> + + <Form.Group as={Row} controlId="btmMenge"> + <Form.Label column sm="2"> + Menge + </Form.Label> + <Col sm="10"> + <Form.Control name="btmMenge" type="number" min="1" max={maxMenge} defaultValue="0" /> + </Col> + </Form.Group> + <Form.Group as={Row} controlId="datum"> + <Form.Label column sm="2"> + Datum + </Form.Label> + <Col sm="10"> + <Form.Control name="datum" type="date" value={date} onChange={e => setDate(moment(e.target.value).format("YYYY-MM-DD"))} /> + </Col> + </Form.Group> + + {typ.toLowerCase() === 'zugang' ? renderZugang() : null} + {typ.toLowerCase() === 'abgang' ? renderAbgang() : null} + + </Modal.Body> + <Modal.Footer> + <Button variant="danger" onClick={hideModal}>Abbrechen</Button> + <Button variant="primary" type="submit">Bestätigen</Button> + </Modal.Footer> + </Form> + </Modal> + ) +} + +export default NeueBuchungModal; + diff --git a/frontend/src/modals/PersonalAddModal.js b/frontend/src/modals/PersonalAddModal.js index abaf275edae8a6bd7e6f62b40823782477fd3ead..dde92bfb71c2c49a147de38d183b548f52a31c58 100644 --- a/frontend/src/modals/PersonalAddModal.js +++ b/frontend/src/modals/PersonalAddModal.js @@ -61,7 +61,7 @@ function PersonalAddModal(props) { return; } - await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/benutzer/${newUsername}/checkUsername`, { + await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/benutzer/${newUsername}/checkUsername`, { method: 'POST', }).then((res) => { if (res.status === 200) { diff --git a/frontend/src/modals/PersonalEditModal.js b/frontend/src/modals/PersonalEditModal.js index 28312cf8ef98a8cdf2195966d66e24f9575598de..15edf14426503016276d954723892585b1911dd2 100644 --- a/frontend/src/modals/PersonalEditModal.js +++ b/frontend/src/modals/PersonalEditModal.js @@ -68,7 +68,7 @@ function PersonalUpdateModal(props) { } if (newUsername !== nutzername && newUsername) { - await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${id}/benutzer/${newUsername}/checkUsername`, { + await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/benutzer/${newUsername}/checkUsername`, { method: 'POST', }).then((res) => { if (res.status === 200) { diff --git a/frontend/src/modals/UpdateBuchungModal.js b/frontend/src/modals/UpdateBuchungModal.js index 8b1e13d76dfaa34d83e41f95231543f9a963052e..0977464e09eb7edf8e92ce7f9c30beed6345ac74 100644 --- a/frontend/src/modals/UpdateBuchungModal.js +++ b/frontend/src/modals/UpdateBuchungModal.js @@ -1,20 +1,21 @@ -import React from 'react'; +import React, {useState, useEffect} from 'react'; import { Modal, Button, Form, Row, Col } from 'react-bootstrap'; import { useSnackbar } from 'notistack'; import { useParams } from 'react-router-dom'; - function UpdateBuchungModal(props) { - // let apothekeId = sessionStorage.getItem('apothekeId'); + const moment = require('moment'); + const [buchung, setBuchung] = useState(props.buchung); + const { apoId } = useParams(); // eslint-disable-next-line let {lieferanten, aerzte, empfaenger} = props; const { enqueueSnackbar } = useSnackbar(); const sendUpdateRequest = async (buchungData) => { - const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${props.buchung.id}`, { + const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${buchung.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', @@ -38,12 +39,10 @@ function UpdateBuchungModal(props) { } - - const updateBuchung = event => { event.preventDefault(); - if (props.buchung.typ.toLowerCase() === 'zugang') { + if (buchung.typ.toLowerCase() === 'zugang') { let { anforderungsschein, btmMenge, lieferant, pruefdatum, datum } = event.target; let buchungData = { benutzer: props.user.id, @@ -56,7 +55,7 @@ function UpdateBuchungModal(props) { datum: datum.value } sendUpdateRequest(buchungData); - } else if (props.buchung.typ.toLowerCase() === 'abgang') { + } else if (buchung.typ.toLowerCase() === 'abgang') { let { btmMenge, rezept, empfaenger, arzt, pruefdatum, datum} = event.target; let buchungData = { benutzer: props.user.id, @@ -73,10 +72,25 @@ function UpdateBuchungModal(props) { } } - + const checkPruefdatum = () => { + if(buchung.pruefdatum) { + return buchung.pruefdatum >= buchung.datum; + }else { + return true; + } + } + + const hideModal = () => { + props.onHide(); + setBuchung(props.buchung); + } + + useEffect(() => { + setBuchung(props.buchung); + }, [props.buchung]); - function Zugang({ buchung }) { + function Zugang() { if (buchung.typ) { if (buchung.typ.toLowerCase() === 'zugang') { return ( @@ -95,7 +109,6 @@ function UpdateBuchungModal(props) { </Form.Label> <Col sm="10"> <Form.Control name="lieferant" defaultValue={buchung.lieferant.name} required as="select"> - {console.log('lieferanten', lieferanten)} {lieferanten.map(l => <option key={l.id} value={l.id}>{l.name}</option>)} </Form.Control> </Col> @@ -106,7 +119,7 @@ function UpdateBuchungModal(props) { return null; } - function Abgang({ buchung }) { + function Abgang() { if (buchung.typ) { if (buchung.typ.toLowerCase() === 'abgang') { return ( @@ -152,7 +165,7 @@ function UpdateBuchungModal(props) { size="lg" aria-labelledby="contained-modal-title-vcenter" centered - onExiting={props.onHide} + onExiting={hideModal} backdrop="static" > <Modal.Header closeButton> @@ -167,7 +180,7 @@ function UpdateBuchungModal(props) { Datum </Form.Label> <Col sm="10"> - <Form.Control name="datum" type="date" defaultValue={props.buchung.datum} /> + <Form.Control name="datum" type="date" value={moment(buchung.datum).format("YYYY-MM-DD")} onChange={e => {setBuchung({...buchung, datum:e.target.value})}} /> </Col> </Form.Group> <Form.Group as={Row} controlId="btmMenge"> @@ -175,7 +188,7 @@ function UpdateBuchungModal(props) { Menge </Form.Label> <Col sm="10"> - <Form.Control name="btmMenge" type="number" min="1" defaultValue={props.buchung.menge} /> + <Form.Control name="btmMenge" type="number" min="1" defaultValue={buchung.menge} /> </Col> </Form.Group> <Form.Group as={Row} controlId="pruefdatum"> @@ -183,15 +196,15 @@ function UpdateBuchungModal(props) { Prüfdatum </Form.Label> <Col sm="10"> - <Form.Control name="pruefdatum" type="date" defaultValue={props.buchung.pruefdatum} /> + <Form.Control name="pruefdatum" isInvalid={!checkPruefdatum()} type="date" value={moment(buchung.pruefdatum).format("YYYY-MM-DD")} onChange={e => {setBuchung({...buchung, pruefdatum:e.target.value})}} /> </Col> </Form.Group> - <Zugang buchung={props.buchung} /> - <Abgang buchung={props.buchung} /> + <Zugang /> + <Abgang /> </Modal.Body> <Modal.Footer> - <Button variant="danger" onClick={props.onHide}>Abbrechen</Button> - <Button variant="primary" type="submit">Bestätigen</Button> + <Button variant="danger" onClick={props.onHide}>Abbrechen</Button> + <Button variant="primary" disabled={!checkPruefdatum()} type="submit">Bestätigen</Button> </Modal.Footer> </Form> </Modal> diff --git a/frontend/src/modals/UserDetailsUpdateModal.js b/frontend/src/modals/UserDetailsUpdateModal.js index b20df79afe39b5cb0a68de8d517df9ca0c38464c..bf8312e575cc42bd6a8db1be97f56a6f7086aac5 100644 --- a/frontend/src/modals/UserDetailsUpdateModal.js +++ b/frontend/src/modals/UserDetailsUpdateModal.js @@ -95,7 +95,7 @@ function UserDetailsUpdateModal(props) { } if (newUsername !== nutzername && newUsername) { - const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/benutzer/${newUsername}/checkUsername`, { + const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/benutzer/${newUsername}/checkUsername`, { method: 'POST', }).catch((err) => { console.log(err);