diff --git a/Hotel app/frontend/package.json b/Hotel app/frontend/package.json index ff04af3..eedbc93 100644 --- a/Hotel app/frontend/package.json +++ b/Hotel app/frontend/package.json @@ -8,6 +8,7 @@ "material-table": "^1.54.2", "react": "^16.12.0", "react-dom": "^16.12.0", + "react-qr-reader": "^2.2.1", "react-scripts": "0.9.5", "semantic-ui-react-form-validator": "^1.0.2" }, diff --git a/Hotel app/frontend/src/App.js b/Hotel app/frontend/src/App.js index 5605f51..c4d67e4 100644 --- a/Hotel app/frontend/src/App.js +++ b/Hotel app/frontend/src/App.js @@ -1,13 +1,21 @@ import React, { Component } from 'react'; import {BrowserRouter , Route , Switch} from 'react-router-dom'; import { PrivateRoute } from './components/PrivateRoute'; +import { PrivateRouteCustomer } from './components/PrivateRouteCustomer'; import Registerform from './components/Registerform'; import Loginform from './components/Loginform'; import Main from './components/Main'; import Menumanagement from './components/Menumanagement'; import Additem from './components/Additem'; import Updateitem from './components/Updateitem'; -import {isLoggedIn} from './components/auth'; +import Customerform from './components/Customer_details'; +import {isLoggedInManager} from './components/auth'; +import {isLoggedInCustomer} from './components/auth'; +import Example from './components/QRscanner'; +import Customermenu from './components/Customermenu'; +import Checkout from './components/Checkout'; +import Pay from './components/Pay'; +import Home from './components/Home'; class App extends Component { @@ -15,12 +23,18 @@ class App extends Component { return ( - + + - + + + + + + ); diff --git a/Hotel app/frontend/src/components/Additem.js b/Hotel app/frontend/src/components/Additem.js index b2ad4e4..4a74686 100644 --- a/Hotel app/frontend/src/components/Additem.js +++ b/Hotel app/frontend/src/components/Additem.js @@ -62,13 +62,7 @@ const additem = () => { window.location.replace("/add") } -const updateitem = () => { - window.location.replace("/update") -} -const deleteitem = () => { - window.location.replace("/delete") -} export default function ClippedDrawer(props) { @@ -120,7 +114,7 @@ export default function ClippedDrawer(props) {
- + @@ -134,12 +128,6 @@ export default function ClippedDrawer(props) { - - - - - - diff --git a/Hotel app/frontend/src/components/Card.js b/Hotel app/frontend/src/components/Card.js new file mode 100644 index 0000000..ffe32fa --- /dev/null +++ b/Hotel app/frontend/src/components/Card.js @@ -0,0 +1,63 @@ +import React,{useState, useEffect} from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; + + + +const useStyles = makeStyles({ + card: { + minWidth: 300, + maxWidth: 1000, + margin: "auto", + marginTop: 20, + marginBottom: 20, + borderRadius: 10 + }, + bullet: { + display: 'inline-block', + margin: '0 2px', + transform: 'scale(0.8)', + }, + title: { + fontSize: 14, + }, + pos: { + marginBottom: 12, + }, +}); + + +export default function SimpleCard(props) { + const classes = useStyles(); + const bull = ; + const additem = props.additem + return ( +
+ {props.data.map((x,i) => ( + + + + FoodItem-ID: {x.id} + + + {x.name} + + + {x.description} + + + Price: Rs.{x.amount} + + + + + + + ))} +
+ ); +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Cart.js b/Hotel app/frontend/src/components/Cart.js new file mode 100644 index 0000000..9097dfc --- /dev/null +++ b/Hotel app/frontend/src/components/Cart.js @@ -0,0 +1,83 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItem from '@material-ui/core/ListItem'; +import List from '@material-ui/core/List'; +import Divider from '@material-ui/core/Divider'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; +import CloseIcon from '@material-ui/icons/Close'; +import Slide from '@material-ui/core/Slide'; +import AddIcon from '@material-ui/icons/Add'; +import RemoveIcon from '@material-ui/icons/Remove'; + +const useStyles = makeStyles(theme => ({ + appBar: { + position: 'relative', + backgroundColor: 'black' + }, + title: { + marginLeft: theme.spacing(2), + flex: 1, + }, + but: { + margin: "auto" + } +})); + +const Transition = React.forwardRef(function Transition(props, ref) { + return ; +}); + + + +export default function FullScreenDialog(props) { + const classes = useStyles(); + const [open, setOpen] = React.useState(false); + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( +
+ + + + + + + + + Cart + + + + + {Object.keys(props.food).map((key,i) => ( + + + props.handleRemove(key,i)} /> + {props.food[key].quantity} + props.handleAdd(key,i)} /> + + ))} + + + + + + + +
+ ); +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Checkout.js b/Hotel app/frontend/src/components/Checkout.js new file mode 100644 index 0000000..d6f8139 --- /dev/null +++ b/Hotel app/frontend/src/components/Checkout.js @@ -0,0 +1,27 @@ +import React, { useEffect } from 'react'; +import {deleteTokensCustomer} from './auth'; +import './customer.css' + +export default function Checkout(){ + + + const handleOrder = () => { + window.location.replace("/place_order"); + } + + const handleCheckout = () => { + deleteTokensCustomer(); + window.location.replace("/customer") + } + + return ( +
+
+

Wanna Order Again??

+ + See you next time ;) + +
+
+ ) +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Customer_details.js b/Hotel app/frontend/src/components/Customer_details.js new file mode 100644 index 0000000..85eaeeb --- /dev/null +++ b/Hotel app/frontend/src/components/Customer_details.js @@ -0,0 +1,154 @@ +import React from 'react'; +import {Link} from 'react-router-dom'; +import Navbar from './Navbar'; +import "./forms.css"; +import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles'; +import TextField from '@material-ui/core/TextField'; +import Button from '@material-ui/core/Button'; +import Container from '@material-ui/core/Container'; +import './customer.css' + + +export default class Customerform extends React.Component { + state = { + name : "", + email : "", + mobileno : 0, + guests : 0, + nameError : "", + emailError : "", + mobileError : "", + guestsError : "", + toggle : false + }; + + + validate = () => { + let nameError = ""; + let emailError = ""; + let mobileError = ""; + let guestsError = ""; + + if (!this.state.name) { + nameError = "Field Empty!!"; + } + + if (!this.state.mobileno) { + mobileError = "Field Empty!!"; + } + + if (!this.state.email.includes("@")) { + emailError = "Invalid Email"; + } + + if(!this.state.guests){ + guestsError = "Field Empty!!"; + } + + if (emailError || nameError || mobileError || guestsError) { + this.setState({ emailError, nameError, mobileError, guestsError }); + this.toggle=true; + return false; + } + + return true; + }; + + recieve = async() => { + const name = this.state.name; + const email = this.state.email; + const mobile = this.state.mobileno; + const guests = this.state.guests; + const user = {name, email, mobile, guests}; + const isValid = this.validate(); + if(isValid){ + fetch('/customer_details', { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(user) + }).then( res => res.json()) + .then(data=>{ + localStorage.setItem('customer_access_token', data.customer_access_token); + + localStorage.setItem('customer_email', data.email); + + if (localStorage.getItem("customer_access_token") !== null && localStorage.getItem("customer_access_token")!=="undefined") { + window.location.replace("/scan") + } + else{ + alert(data.error) + } + }).catch(err => console.log(err)); + + } + else{ + console.log("bye") + } + }; + + + render(){ + return ( +
+ +
+

Customer Details

+ this.setState({ name: event.target.value })} + error={this.toggle} + helperText={this.state.nameError} + variant="outlined" + fullWidth="true" + margin="normal" + /> +
+ this.setState({ email: event.target.value })} + error={this.toggle} + helperText={this.state.emailError} + variant="outlined" + margin="normal" + fullWidth="true" + /> +
+ this.setState({ mobileno: event.target.value })} + error={this.toggle} + helperText={this.state.mobileError} + variant="outlined" + margin="normal" + fullWidth="true" + /> +
+ this.setState({ guests: event.target.value })} + error={this.toggle} + helperText={this.state.guestsError} + variant="outlined" + margin="normal" + fullWidth="true" + /> +
+
+ +
+
+
+
+ ); + } +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Customermenu.js b/Hotel app/frontend/src/components/Customermenu.js new file mode 100644 index 0000000..99cc085 --- /dev/null +++ b/Hotel app/frontend/src/components/Customermenu.js @@ -0,0 +1,105 @@ +import React,{useState, useEffect} from 'react'; +import Card from './Card'; +import Cart from './Cart'; +import './customer.css'; +import {isLoggedInCustomer} from './auth'; + + +export default class Customermenu extends React.Component { + constructor(props){ + super(props) + this.state = { + data1: [], + food: [], + grandtotal: 0, + }; + this.additem = this.additem.bind(this); + this.handleRemove = this.handleRemove.bind(this); + this.handleAdd = this.handleAdd.bind(this); + this.handleConfirm = this.handleConfirm.bind(this); + } + + componentDidMount(){ + fetch("/menu").then( res => res.json()).then(data =>{ + this.setState({data1: data.food_items}) + }) + } + + additem = (x,i) => { + const item = {'name':x.name,'price':x.amount,'quantity':1} + this.setState({food: this.state.food.concat(item)}) + this.setState(prevState => { + return {grandtotal: prevState.grandtotal + x.amount} + }) + alert("Item added to cart"); + } + + handleRemove = (key,i) => { + const item = this.state.food[i].price; + this.setState(prevState => { + let fooditem = {...prevState.food} + fooditem[i].quantity = fooditem[i].quantity - 1; + return { fooditem } + }) + this.setState(prevState => { + console.log(this.state.food[i].price) + return {grandtotal: prevState.grandtotal - this.state.food[i].price} + }) + }; + + handleAdd = (i) => { + this.setState(prevState => { + let fooditem = {...prevState.food} + fooditem[i].quantity = fooditem[i].quantity + 1; + return {fooditem} + }) + this.setState(prevState => { + return {grandtotal: prevState.grandtotal + this.state.food[i].price} + }) + }; + + handleConfirm = () => { + if(isLoggedInCustomer()){ + const sessid = localStorage.getItem("customer_access_token"); + const food = JSON.stringify(this.state.food); + const grandtotal = this.state.grandtotal; + const customerorder = {'sessionid':sessid,food,grandtotal} + console.log(JSON.stringify(customerorder)); + fetch('/order', { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(customerorder) + }).then(res => { + if(res.ok){ + alert("Order Confirmed"); + window.location.replace("/pay") + } + }) + } + else{ + console.log("hello") + } + }; + + render(){ + return ( +
+
+ +
+ +
+ ) + } +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Home.js b/Hotel app/frontend/src/components/Home.js new file mode 100644 index 0000000..766d191 --- /dev/null +++ b/Hotel app/frontend/src/components/Home.js @@ -0,0 +1,24 @@ +import React from 'react'; +import './customer.css' + +export default function Home(){ + + const handleCustomer = () => { + window.location.replace("/customer"); + } + + const handleHotel = () => { + window.location.replace("/register") + } + + return ( +
+
+

PROJECT: DINE-IN

+ + +
+ +
+ ) +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Loginform.js b/Hotel app/frontend/src/components/Loginform.js index 67e7523..2166ae6 100644 --- a/Hotel app/frontend/src/components/Loginform.js +++ b/Hotel app/frontend/src/components/Loginform.js @@ -51,7 +51,7 @@ export default class Registerform extends React.Component { }).then( res => res.json()) .then(data=>{ localStorage.setItem('access_token', data.access_token); - localStorage.setItem('username', data.email) + localStorage.setItem('email', data.email) if (localStorage.getItem("access_token") !== null && localStorage.getItem("access_token")!=="undefined") { window.location.replace("/main") diff --git a/Hotel app/frontend/src/components/Order.js b/Hotel app/frontend/src/components/Order.js index 3bacda1..43703a6 100644 --- a/Hotel app/frontend/src/components/Order.js +++ b/Hotel app/frontend/src/components/Order.js @@ -12,7 +12,7 @@ export default function Order(){ fetch("/order").then( res => res.json()).then(data =>{ setData(data.order_items) }) - }, 20000); + }, 3000); return () => clearInterval(interval); }, []); @@ -43,10 +43,6 @@ export default function Order(){ name: "Orderid", prop: "orderid" }, - { - name: "Userid", - prop: "userid" - }, { name: "Status", prop: "status" @@ -62,6 +58,10 @@ export default function Order(){ { name: "Amount", prop: "amount" + }, + { + name: "Datetime", + prop: "datetime" } ]} /> diff --git a/Hotel app/frontend/src/components/Ordertable.js b/Hotel app/frontend/src/components/Ordertable.js index 0a14304..86c01ca 100644 --- a/Hotel app/frontend/src/components/Ordertable.js +++ b/Hotel app/frontend/src/components/Ordertable.js @@ -18,13 +18,12 @@ const useStyles = makeStyles({ const test = fooditem => { return ( -
    - { - Object.keys(fooditem).map(key => { - return
  • {key} x{fooditem[key]}
  • - }) - } -
+
    + {fooditem.map((x,i) => { + const hh = x.quantity*x.price; + return
  • {x.name} x{x.quantity}: Rs.{hh}
  • + })} +
) } @@ -56,6 +55,7 @@ const row = (x,i,props) => { {header.map((y, k) => ( + {console.log(x['food'])} {y.prop === 'food' ? test(JSON.parse(x[y.prop])) : x[y.prop]} ))} diff --git a/Hotel app/frontend/src/components/Pay.js b/Hotel app/frontend/src/components/Pay.js new file mode 100644 index 0000000..5eea974 --- /dev/null +++ b/Hotel app/frontend/src/components/Pay.js @@ -0,0 +1,139 @@ +import React, { useEffect } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; +import TextField from '@material-ui/core/TextField'; +import './customer.css'; + +const useStyles = makeStyles({ + card: { + minWidth: 275, + maxWidth: 700, + margin: "auto", + marginTop: 200, + borderRadius: "1rem", + border: "2px solid black" + }, + bullet: { + display: 'inline-block', + margin: '0 2px', + transform: 'scale(0.8)', + }, + title: { + fontSize: 14, + }, + pos: { + marginBottom: 12, + }, +}); + + + +export default function SimpleCard() { + const classes = useStyles(); + const bull = ; + const [data1, setData] = React.useState([]); + const [name, setName] = React.useState(""); + const [number,setNumber] = React.useState(0); + const [nameError, setNameerror] = React.useState(""); + const [numberError, setNumbererror] = React.useState(""); + const [toggle, setToggle] = React.useState(false); + + useEffect(() => { + const sessid = localStorage.getItem("customer_access_token"); + fetch("/getpayment",{ + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({'sessionid':sessid}) + }).then( res => res.json()).then(data =>{ + setData(data.customer_details) + console.log(data) + }) + },[]); + + const validate = () => { + let namet = ""; + let numbert = ""; + if (!name) { + namet="Field Empty" + } + + if(!number){ + numbert="Field Empty" + } + + if (namet || numbert) { + setNameerror(namet); + setNumbererror(numbert); + setToggle(true); + return false; + } + + return true; +}; + +const handleClick = () => { + if(validate()){ + console.log("hi") + window.location.replace("/checkout") + } + else{ + console.log("hello") + } +} + + return ( +
+ + + + + {data1.name} + + + Order Id: {data1.orderid} +
+ Table No: {data1.tableno} +
+ Subtotal: {data1.amount} +
+
+
+ setName(event.target.value)} + error={toggle} + helperText={nameError} + variant="outlined" + margin="normal" + fullWidth="true" + /> +
+ setNumber(event.target.value)} + error={toggle} + helperText={numberError} + variant="outlined" + margin="normal" + fullWidth="true" + /> +
+
+
+ + + +
+
+ ); +} \ No newline at end of file diff --git a/Hotel app/frontend/src/components/PrivateRoute.js b/Hotel app/frontend/src/components/PrivateRoute.js index b17ae38..e5628a8 100644 --- a/Hotel app/frontend/src/components/PrivateRoute.js +++ b/Hotel app/frontend/src/components/PrivateRoute.js @@ -1,12 +1,12 @@ import React from 'react'; import {Route,Redirect } from "react-router-dom"; -import {isLoggedIn} from './auth'; +import {isLoggedInManager} from './auth'; export const PrivateRoute = ({ component: Component, ...rest }) => ( - isLoggedIn() ? ( + isLoggedInManager() ? ( ) : ( ( + + isLoggedInCustomer() ? ( + + ) : ( + + ) + } + /> +); \ No newline at end of file diff --git a/Hotel app/frontend/src/components/QRscanner.js b/Hotel app/frontend/src/components/QRscanner.js new file mode 100644 index 0000000..6e9f0bf --- /dev/null +++ b/Hotel app/frontend/src/components/QRscanner.js @@ -0,0 +1,69 @@ +import React, { Component } from 'react' +import QrReader from 'react-qr-reader' + +export default class Example extends Component { + constructor(props){ + super(props) + this.state = { + delay: 500, + result: '', + } + + this.handleScan = this.handleScan.bind(this) + } + handleScan(data){ + if(data){ + this.setState({ result: data }) + if (localStorage.getItem("customer_access_token") !== null && localStorage.getItem("customer_access_token")!=="undefined") { + const sessionidx = localStorage.getItem("customer_access_token") + fetch(`/add_table/${sessionidx}`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(this.state.result) + }).then( res => { + if(res.ok){ + window.location.replace("/place_order") + } + else{ + console.log("data not sent") + } + }) + } + else{ + alert("Customer details not entered") + } + } + else{ + console.log("Not working") + } + } + + handleError(err){ + console.error(err) + } + render(){ + const previewStyle = { + height: 500, + width: 800, + margin: "auto" + } + + return( +
+ +

+














+

Result: {this.state.result}

+

+
+ ) + } +} + \ No newline at end of file diff --git a/Hotel app/frontend/src/components/Updateitem.js b/Hotel app/frontend/src/components/Updateitem.js index ed5d1f4..a7498db 100644 --- a/Hotel app/frontend/src/components/Updateitem.js +++ b/Hotel app/frontend/src/components/Updateitem.js @@ -114,7 +114,7 @@ export default function ClippedDrawer() {
- + diff --git a/Hotel app/frontend/src/components/auth.js b/Hotel app/frontend/src/components/auth.js index 7a675b0..ccbc18d 100644 --- a/Hotel app/frontend/src/components/auth.js +++ b/Hotel app/frontend/src/components/auth.js @@ -1,16 +1,36 @@ -export function isLoggedIn() { +export function isLoggedInManager() { return localStorage.getItem("access_token")!==null && localStorage.getItem("access_token")!=="undefined"; } + +export function isLoggedInCustomer() { + return localStorage.getItem("customer_access_token")!==null && localStorage.getItem("customer_access_token")!=="undefined"; +} export function deleteTokens(){ localStorage.removeItem("access_token"); - localStorage.removeItem("username"); + localStorage.removeItem("email"); } + + export function deleteTokensCustomer(){ + localStorage.removeItem("customer_access_token"); + localStorage.removeItem("customer_email"); + } + export function requiredAuth(nextState, replace) { - if (!isLoggedIn()) { + if (!isLoggedInManager()) { replace({ pathname: '/', state: { nextPathname: nextState.location.pathname } }) } - } \ No newline at end of file + } + + export function requiredAuthCustomer(nextState, replace) { + if (!isLoggedInCustomer()) { + replace({ + pathname: '/customer', + state: { nextPathname: nextState.location.pathname } + }) + } + } + diff --git a/Hotel app/frontend/src/components/customer.css b/Hotel app/frontend/src/components/customer.css new file mode 100644 index 0000000..332964e --- /dev/null +++ b/Hotel app/frontend/src/components/customer.css @@ -0,0 +1,56 @@ +.bg { + /* The image used */ + background-image: url(../images/Foodbg.jpg) ; + height: 100%; + width: 100%; + position: fixed; + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + +.cuss { + background-color: wheat; + min-width: 300px; + max-width: 700px; + margin: auto; + margin-top: 200px; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + border: 2px solid black; + border-radius: 5%; +} + +.bg2 { + background-image: url(../images/menuwall.jpg) ; + height: 100%; + width: 100%; + position: fixed; + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + +.bg3 { + background-image: url(../images/jj.jpg) ; + height: 100%; + width: 100%; + position: fixed; + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + +.border { + border-style: solid; + border-width: 5px; +} + +.bghome { + background-image: url(../images/home.jpg) ; + height: 100%; + width: 100%; + position: fixed; + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} \ No newline at end of file diff --git a/Hotel app/frontend/src/images/Foodbg.jpg b/Hotel app/frontend/src/images/Foodbg.jpg new file mode 100644 index 0000000..a16b8a8 Binary files /dev/null and b/Hotel app/frontend/src/images/Foodbg.jpg differ diff --git a/Hotel app/frontend/src/images/home.jpg b/Hotel app/frontend/src/images/home.jpg new file mode 100644 index 0000000..ecf9ee5 Binary files /dev/null and b/Hotel app/frontend/src/images/home.jpg differ diff --git a/Hotel app/frontend/src/images/jj.jpg b/Hotel app/frontend/src/images/jj.jpg new file mode 100644 index 0000000..2204ac2 Binary files /dev/null and b/Hotel app/frontend/src/images/jj.jpg differ diff --git a/Hotel app/frontend/src/images/menuwall.jpg b/Hotel app/frontend/src/images/menuwall.jpg new file mode 100644 index 0000000..4e7fb1e Binary files /dev/null and b/Hotel app/frontend/src/images/menuwall.jpg differ diff --git a/Hotel app/server/app.py b/Hotel app/server/app.py index 1fc531f..af7501d 100644 --- a/Hotel app/server/app.py +++ b/Hotel app/server/app.py @@ -1,7 +1,10 @@ +from datetime import datetime from flask import Flask, request, render_template, jsonify from flask_sqlalchemy import SQLAlchemy +from sqlalchemy import desc from flask_jwt_extended import JWTManager from flask_jwt_extended import (create_access_token, create_refresh_token) +import json app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' @@ -19,19 +22,33 @@ class User(db.Model): password = db.Column(db.String(60), nullable=False) def __repr__(self): - return f"User('{self.firstname}','{self.lastname}', '{self.email}','{self.password}')" + return f"User('{self.id}', '{self.firstname}', '{self.lastname}', '{self.email}', '{self.password}')" + + +class Customer(db.Model): + customer_id = db.Column(db.Integer, primary_key=True) + customer_name = db.Column(db.String(20), nullable=False) + customer_email = db.Column(db.String(120), nullable=False) + mobileno = db.Column(db.Integer, nullable=False) + no_of_guests = db.Column(db.Integer, nullable=False) + sessionid = db.Column(db.String(120), nullable=False) + tableno = db.Column(db.String(40)) + orders = db.relationship('Order', backref='author', lazy=True) + + def __repr__(self): + return f"Customer('{self.customer_id}', '{self.customer_name}', '{self.customer_email}', '{self.mobileno}', '{self.no_of_guests}', '{self.tableno}')" class Order(db.Model): orderid = db.Column(db.Integer, unique=True, nullable=False, primary_key=True) - status = db.Column(db.String(30),nullable=False) - userid = db.Column(db.Integer, unique=True, nullable=False) + status = db.Column(db.String(30), nullable=False) food = db.Column(db.Text, nullable=False) - tableno = db.Column(db.Integer, nullable=False) amount = db.Column(db.Integer, nullable=False) + date_ordered = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) + tableno = db.Column(db.String(40), db.ForeignKey('customer.tableno'), nullable=False) def __repr__(self): - return f"Order('{self.orderid}','{self.status}', '{self.userid}', '{self.food}', '{self.tableno}', '{self.amount}')" + return f"Order('{self.orderid}', '{self.status}', '{self.food}', '{self.amount}', '{self.tableno}','{self.date_ordered}')" class Food(db.Model): @@ -152,6 +169,67 @@ def menu(): return jsonify({'food_items': items}) +@app.route('/customer_details', methods=['GET', 'POST']) +def customer_details(): + if request.method == 'POST': + user_data = request.get_json() + + access_token_customer = create_access_token(identity=user_data['email']) + refresh_token_customer = create_refresh_token(identity=user_data['email']) + + if Customer.query.filter_by(sessionid=access_token_customer).first(): + return {"error": "Session already taking place on another window"} + + new_user = Customer( + customer_name=user_data['name'], + customer_email=user_data['email'], + mobileno=user_data['mobile'], + no_of_guests=user_data['guests'], + sessionid=access_token_customer + ) + + db.session.add(new_user) + db.session.commit() + + return { + 'email': user_data['email'], + 'customer_access_token': access_token_customer, + 'customer_refresh_token': refresh_token_customer + } + else: + user_data = request.get_json() + sessid = user_data['sessionid'] + customer = Customer.query.filter_by(sessionid=sessid).first() + food = customer.orders.order_by(desc(customer.orders.date_ordered)).first() + print(food) + + return jsonify({'customer_details': food}) + + +@app.route('/add_table/', methods=['POST']) +def add_table(sessionidx): + data = request.get_json() + find_customer = Customer.query.filter_by(sessionid=sessionidx).first() + find_customer.tableno = data + + db.session.commit() + + return 'Done' + + +@app.route('/getpayment', methods=['POST']) +def cc(): + user_data = request.get_json() + sessid = user_data['sessionid'] + customer = Customer.query.filter_by(sessionid=sessid).first() + order = customer.orders[-1] + food = json.loads(order.food) + print(type(food)) + tt = {'id': customer.customer_id, 'name': customer.customer_name, 'food': json.dumps(food), 'tableno': customer.tableno, 'amount': order.amount, 'orderid': order.orderid} + + return jsonify({'customer_details': tt}) + + @app.route('/order_delete', methods=['POST']) def order_delete(): if request.method == 'POST': @@ -171,11 +249,27 @@ def order_food(): items = [] for item in order_list: - items.append({'orderid': item.orderid, 'status': item.status, 'userid': item.userid, 'food': item.food, 'tableno': item.tableno, 'amount': item.amount}) + items.append({'orderid': item.orderid, 'status': item.status, 'food': item.food, 'tableno': item.tableno, 'amount': item.amount, 'datetime': item.date_ordered}) - print(items) + print(items) return jsonify({'order_items': items}) + else: + order_data = request.get_json() + sessid = order_data['sessionid'] + customer = Customer.query.filter_by(sessionid=sessid).first() + + data = Order( + status='Food is being prepared', + food=order_data['food'], + amount=order_data['grandtotal'], + tableno=customer.tableno + ) + + db.session.add(data) + db.session.commit() + + return 'Done' @app.route('/update_status/', methods=['GET', 'POST']) diff --git a/README.md b/README.md index 335c48a..33225df 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ # DINE-IN +# Prerequisites: Download nodejs and Python in your desktop. +//Instructions of git pull to be added + + +After pulling the code in your computer's folder: + + +1.Open command line/terminal + + +2.Go to the project's directory using cd commands + + +3.cd DINE-IN,cd Hotel App + + +4.Once Hotel app's folder is reached:- + + +# For Frontend: + +Go to frontend folder using cd frontend and +# Type the command: npm start + + +# For Backend: + + +Go to server folder using cd server and +# Type the command: python3 app.py +You can open 2 separate tabs of command line to run both frontend and backend simultaneously.