Skip to content
Snippets Groups Projects
Commit 54508466 authored by meskio's avatar meskio :tent:
Browse files

Improve the product picker

parent b209ab4e
No related branches found
No related tags found
No related merge requests found
import React from 'react';
import { Form, Row, Col, Button } from 'react-bootstrap';
import { Typeahead } from 'react-bootstrap-typeahead';
import Fetcher from './Fetcher';
import { printMoney } from './util';
class ProductPicker extends React.Component {
constructor(props) {
super(props);
this.state = {
code: "",
products: [],
};
}
delPick(index) {
let picks = this.props.picks;
picks.splice(index, 1);
this.props.setPicks(picks);
}
setAmmount(index, ammount) {
let picks = this.props.picks;
picks[index].ammount = parseInt(ammount);
this.props.setPicks(picks);
}
setCode(codeStr) {
const code = parseInt(codeStr);
const product = this.state.products.find(p => p.code === code);
if (product === undefined) {
this.setState({ code: codeStr });
} else {
this.pickProduct(product);
}
}
pickProduct(product) {
let picks = this.props.picks;
picks.push({
code: product.code,
name: product.name,
price: product.price,
ammount: 1
});
this.props.setPicks(picks);
this.setState({ code: "" });
}
render() {
const rows = this.props.picks.map((p, i) => {
return (
<Form.Group key={p.code} as={Row}>
<Col>
<p>{p.code}</p>
</Col>
<Col sm={4}>
<p>{p.name}</p>
</Col>
<Col>
{printMoney(p.price)+""}
</Col>
{this.props.ammount &&
<Col>
<Form.Control
type="number" min="1"
placeholder="cantidad"
value={p.ammount}
onChange={e => this.setAmmount(i, e.target.value)}
/>
</Col>
}
<Col sm={1}>
<Button variant="danger" onClick={() => this.delPick(i)}>-</Button>
</Col>
</Form.Group>
)
});
return (
<Fetcher url="/api/product" onFetch={products => this.setState({ products })} >
<Row>
<Col>
<h6>Código</h6>
</Col>
<Col sm={4}>
<h6>Nombre</h6>
</Col>
<Col>
<h6>Precio</h6>
</Col>
{this.props.ammount &&
<Col>
<h6>Cantidad</h6>
</Col>
}
<Col sm={1}>
</Col>
</Row>
{rows}
<Form.Group as={Row}>
<Col>
<Form.Control
placeholder="codigo"
value={this.state.code}
onChange={e => this.setCode(e.target.value)}
/>
</Col>
<Col sm={4}>
<Typeahead
id="product-name"
labelKey="name"
options={this.state.products}
onChange={name => this.pickProduct(name[0])}
selected={[]}
/>
</Col>
<Col></Col>
{this.props.ammount &&
<Col></Col>
}
<Col sm={1}></Col>
</Form.Group>
</Fetcher>
);
}
}
export default ProductPicker;
import React from 'react'; import React from 'react';
import { Redirect } from 'react-router-dom'; import { Redirect } from 'react-router-dom';
import Fetcher from '../Fetcher'; import { Container, Row, Col, Button, Alert, Spinner } from 'react-bootstrap';
import PurchaseForm from './PurchaseForm'; import ProductPicker from '../ProductPicker';
import { Row, Col, Button, Alert, Spinner } from 'react-bootstrap';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import AuthContext from '../AuthContext'; import AuthContext from '../AuthContext';
import { printMoney } from '../util'; import { printMoney } from '../util';
const columns = [
{dataField: 'code', text: 'codigo', editable: false},
{dataField: 'name', text: 'nombre', editable: false},
{dataField: 'priceStr', text: 'precio', editable: false},
{dataField: 'ammount', text: 'cantidad', validator: v => {
if (isNaN(v)) {
return {
valid: false,
message: "no es un numero"
};
}
return true;
}},
{dataField: 'del', text: '', editable: false},
]
class Purchase extends React.Component { class Purchase extends React.Component {
static contextType = AuthContext; static contextType = AuthContext;
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
products: [],
purchase: [], purchase: [],
total: 0, total: 0,
purchaseId: null, transactionId: null,
isLoading: false, isLoading: false,
badAuth: false, noMoney: false,
error: null error: null
}; };
} }
addProduct(product) { setPurchase(purchase) {
const code = product.code;
if (this.state.purchase.find(p => p.code === code) !== undefined) {
return false;
}
product.priceStr = printMoney(product.price)+"";
product.del = <Button onClick={() => this.delProduct(code)}>-</Button>;
let purchase = this.state.purchase;
purchase.push(product);
this.setState({ purchase });
this.updateTotal(purchase);
return true;
}
delProduct(code) {
const i = this.state.purchase.findIndex(p => p.code === code);
let purchase = this.state.purchase;
purchase.splice(i,1);
this.setState({purchase});
this.updateTotal(purchase);
}
updateTotal(purchase) {
const add = (acc, p) => acc + (p.price*p.ammount); const add = (acc, p) => acc + (p.price*p.ammount);
const total = purchase.reduce(add, 0); const total = purchase.reduce(add, 0);
this.setState({total}); this.setState({ purchase, total });
} }
send() { send() {
this.setState({isLoading: true, error: null, noMoney: false}); this.setState({isLoading: true, error: null, noMoney: false});
const body = JSON.stringify(this.state.purchase.map(p => { const body = JSON.stringify(this.state.purchase.map(p => {
return { return {
code: parseInt(p.code), code: p.code,
ammount: parseInt(p.ammount) ammount: p.ammount
}; };
})); }));
fetch("/api/purchase", {headers: {'x-authentication': this.context.token}, method: "POST", body}) fetch("/api/purchase", {headers: {'x-authentication': this.context.token}, method: "POST", body})
...@@ -89,7 +46,7 @@ class Purchase extends React.Component { ...@@ -89,7 +46,7 @@ class Purchase extends React.Component {
return response.json(); return response.json();
}) })
.then(p => { .then(p => {
this.setState({purchaseId: p.ID, isLoading: false}); this.setState({transactionId: p.ID, isLoading: false});
}) })
.catch(error => { .catch(error => {
if (error.name === "not-money") { if (error.name === "not-money") {
...@@ -119,23 +76,17 @@ class Purchase extends React.Component { ...@@ -119,23 +76,17 @@ class Purchase extends React.Component {
</Alert> </Alert>
); );
} }
if (this.state.purchaseId !== null) { if (this.state.transactionId !== null) {
return <Redirect to={"/transaction/"+this.state.purchaseId} />; return <Redirect to={"/transaction/"+this.state.transactionId} />;
} }
const purchase = this.state.purchase;
return ( return (
<Fetcher url="/api/product" onFetch={products => this.setState({ products })} > <Container>
{alert} {alert}
<BootstrapTable <ProductPicker ammount
keyField="code" picks={this.state.purchase}
data={ purchase } setPicks={purchase => this.setPurchase(purchase)}
columns={ columns } />
cellEdit={ cellEditFactory({
mode: 'click',
afterSaveCell: () => this.updateTotal(this.state.purchase)
}) } />
<PurchaseForm products={this.state.products} onSubmit={p => this.addProduct(p)} />
<br /> <br />
<Row> <Row>
<Col> <Col>
...@@ -143,11 +94,11 @@ class Purchase extends React.Component { ...@@ -143,11 +94,11 @@ class Purchase extends React.Component {
</Col> </Col>
<Col> <Col>
<div className="text-right"> <div className="text-right">
<Button onClick={() => this.send()}>Enviar</Button> <Button onClick={() => this.send()}>Finalizar compra</Button>
</div> </div>
</Col> </Col>
</Row> </Row>
</Fetcher> </Container>
); );
} }
} }
......
import React from 'react';
import { Col, Form, Button } from 'react-bootstrap';
import { Typeahead } from 'react-bootstrap-typeahead';
import { printMoney } from '../util';
class PurchaseForm extends React.Component {
constructor(props) {
super(props);
this.state = {
codeInvalid: false,
code: "",
product: null,
ammount: 1
};
}
setCode(codeStr) {
const code = parseInt(codeStr);
const product = this.props.products.find(p => p.code === code);
this.setState({
code: codeStr,
product: product,
codeInvalid: product === undefined
});
}
setName(product) {
this.setState({
product,
code: product.code,
codeInvalid: false,
});
}
submit(e) {
e.preventDefault();
if (!this.state.product) {
return
}
let product = this.state.product;
product.ammount = this.state.ammount;
if (this.props.onSubmit(product)) {
this.setState({
code: "",
product: null,
ammount: 1,
codeInvalid: false
});
} else {
this.setState({ codeInvalid: true });
}
}
render() {
if (this.props.products.length === 0) {
return null;
}
return (
<Form onSubmit={e => this.submit(e)}>
<Form.Row>
<Col>
<Form.Control
placeholder="codigo"
value={this.state.code}
onChange={e => this.setCode(e.target.value)}
isInvalid={this.state.codeInvalid}
/>
</Col>
<Col>
<Typeahead
id="product-name"
labelKey="name"
options={this.props.products}
onChange={name => this.setName(name[0])}
selected={this.state.product? [this.state.product]:[]}
/>
</Col>
<Col>
{this.state.product? printMoney(this.state.product.price)+"":"0.00€"}
</Col>
<Col>
<Form.Control
type="number" min="1"
placeholder="cantidad"
value={this.state.ammount}
onChange={e => this.setState({ammount: e.target.value})}
/>
</Col>
<Col>
<Button type="submit">+</Button>
</Col>
</Form.Row>
</Form>
);
}
}
export default PurchaseForm;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment