diff --git a/client/src/components/Invoice/Invoice.js b/client/src/components/Invoice/Invoice.js
index d89a05b7..a111018b 100644
--- a/client/src/components/Invoice/Invoice.js
+++ b/client/src/components/Invoice/Invoice.js
@@ -1,505 +1,630 @@
-import React, { useState, useEffect} from 'react'
-import styles from './Invoice.module.css'
-import { useDispatch, useSelector } from 'react-redux'
-import { useParams } from 'react-router-dom'
-import moment from 'moment'
-import { useHistory } from 'react-router-dom'
-import { toCommas } from '../../utils/utils'
-
-import IconButton from '@material-ui/core/IconButton';
-import DeleteOutlineRoundedIcon from '@material-ui/icons/DeleteOutlineRounded';
-import DateFnsUtils from '@date-io/date-fns';
-import { MuiPickersUtilsProvider, KeyboardDatePicker } from '@material-ui/pickers';
-import TextField from '@material-ui/core/TextField';
-import Autocomplete from '@material-ui/lab/Autocomplete';
-import { makeStyles } from '@material-ui/core/styles';
-import Table from '@material-ui/core/Table';
-import TableBody from '@material-ui/core/TableBody';
-import TableCell from '@material-ui/core/TableCell';
-import TableContainer from '@material-ui/core/TableContainer';
-import TableHead from '@material-ui/core/TableHead';
-import TableRow from '@material-ui/core/TableRow';
-import Paper from '@material-ui/core/Paper';
-import Typography from '@material-ui/core/Typography';
-import InputBase from '@material-ui/core/InputBase';
-import { Container, Grid } from '@material-ui/core';
-import Avatar from '@material-ui/core/Avatar';
-import Divider from '@material-ui/core/Divider';
-import SaveIcon from '@material-ui/icons/Save';
-import Button from '@material-ui/core/Button';
-import Chip from '@material-ui/core/Chip';
-import {initialState} from '../../initialState'
-import currencies from '../../currencies.json'
-import { createInvoice, getInvoice, updateInvoice } from '../../actions/invoiceActions';
-import { getClientsByUser } from '../../actions/clientActions'
-import AddClient from './AddClient';
-import InvoiceType from './InvoiceType';
-import axios from 'axios'
-import { useLocation } from 'react-router-dom'
+import React, { useState, useEffect } from "react";
+import styles from "./Invoice.module.css";
+import { useDispatch, useSelector } from "react-redux";
+import { useParams } from "react-router-dom";
+import moment from "moment";
+import { useHistory } from "react-router-dom";
+import { toCommas } from "../../utils/utils";
+
+import IconButton from "@material-ui/core/IconButton";
+import DeleteOutlineRoundedIcon from "@material-ui/icons/DeleteOutlineRounded";
+import DateFnsUtils from "@date-io/date-fns";
+import {
+ MuiPickersUtilsProvider,
+ KeyboardDatePicker,
+} from "@material-ui/pickers";
+import TextField from "@material-ui/core/TextField";
+import Autocomplete from "@material-ui/lab/Autocomplete";
+import { makeStyles } from "@material-ui/core/styles";
+import Table from "@material-ui/core/Table";
+import TableBody from "@material-ui/core/TableBody";
+import TableCell from "@material-ui/core/TableCell";
+import TableContainer from "@material-ui/core/TableContainer";
+import TableHead from "@material-ui/core/TableHead";
+import TableRow from "@material-ui/core/TableRow";
+import Paper from "@material-ui/core/Paper";
+import Typography from "@material-ui/core/Typography";
+import InputBase from "@material-ui/core/InputBase";
+import { Container, Grid } from "@material-ui/core";
+import Avatar from "@material-ui/core/Avatar";
+import Divider from "@material-ui/core/Divider";
+import SaveIcon from "@material-ui/icons/Save";
+import Button from "@material-ui/core/Button";
+import Chip from "@material-ui/core/Chip";
+import { initialState } from "../../initialState";
+import currencies from "../../currencies.json";
+import {
+ createInvoice,
+ getInvoice,
+ updateInvoice,
+} from "../../actions/invoiceActions";
+import { getClientsByUser } from "../../actions/clientActions";
+import AddClient from "./AddClient";
+import InvoiceType from "./InvoiceType";
+import axios from "axios";
+import { useLocation } from "react-router-dom";
const useStyles = makeStyles((theme) => ({
- root: {
- display: 'flex',
- '& > *': {
- margin: theme.spacing(1),
- },
+ root: {
+ display: "flex",
+ "& > *": {
+ margin: theme.spacing(1),
},
- large: {
- width: theme.spacing(12),
- height: theme.spacing(12),
- },
- table: {
- minWidth: 650,
- },
-
- headerContainer: {
- // display: 'flex'
- paddingTop: theme.spacing(1),
- paddingLeft: theme.spacing(5),
- paddingRight: theme.spacing(1),
- }
- }));
+ },
+ large: {
+ width: theme.spacing(12),
+ height: theme.spacing(12),
+ },
+ table: {
+ minWidth: 650,
+ },
+
+ headerContainer: {
+ // display: 'flex'
+ paddingTop: theme.spacing(1),
+ paddingLeft: theme.spacing(5),
+ paddingRight: theme.spacing(1),
+ },
+}));
const Invoice = () => {
+ const location = useLocation();
+ const [invoiceData, setInvoiceData] = useState(initialState);
+ const [rates, setRates] = useState(0);
+ const [vat, setVat] = useState(0);
+ const [currency, setCurrency] = useState(currencies[0].value);
+ const [subTotal, setSubTotal] = useState(0);
+ const [total, setTotal] = useState(0);
+ const today = new Date();
+ const [selectedDate, setSelectedDate] = useState(
+ today.getTime() + 7 * 24 * 60 * 60 * 1000
+ );
+ const [client, setClient] = useState(null);
+ const [type, setType] = useState("Invoice");
+ const [status, setStatus] = useState("");
+ const { id } = useParams();
+ const clients = useSelector((state) => state.clients.clients);
+ const { invoice } = useSelector((state) => state.invoices);
+ const dispatch = useDispatch();
+ const history = useHistory();
+ const user = JSON.parse(localStorage.getItem("profile"));
+
+ useEffect(() => {
+ getTotalCount();
+ // eslint-disable-next-line
+ }, [location]);
+
+ const getTotalCount = async () => {
+ try {
+ const response = await axios.get(
+ `${process.env.REACT_APP_API}/invoices/count?searchQuery=${user?.result?._id}`
+ );
+ // console.log(response.data);
+ //Get total count of invoice from the server and increment by one to serialized numbering of invoice
+ setInvoiceData({
+ ...invoiceData,
+ invoiceNumber: (Number(response.data) + 1).toString().padStart(3, "0"),
+ });
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ dispatch(getInvoice(id));
+ // eslint-disable-next-line
+ }, [id]);
+
+ useEffect(() => {
+ dispatch(
+ getClientsByUser({ search: user?.result._id || user?.result?.googleId })
+ );
+ // eslint-disable-next-line
+ }, [dispatch]);
+
+ useEffect(() => {
+ if (invoice) {
+ //Automatically set the default invoice values as the ones in the invoice to be updated
+ setInvoiceData(invoice);
+ setRates(invoice.rates);
+ setClient(invoice.client);
+ setType(invoice.type);
+ setStatus(invoice.status);
+ setSelectedDate(invoice.dueDate);
+ }
+ }, [invoice]);
- const location = useLocation()
- const [invoiceData, setInvoiceData] = useState(initialState)
- const [ rates, setRates] = useState(0)
- const [vat, setVat] = useState(0)
- const [currency, setCurrency] = useState(currencies[0].value)
- const [subTotal, setSubTotal] = useState(0)
- const [total, setTotal] = useState(0)
- const today = new Date();
- const [selectedDate, setSelectedDate] = useState(today.getTime() + 7 * 24 * 60 * 60 * 1000);
- const [ client, setClient] = useState(null)
- const [type, setType] = useState('Invoice')
- const [status, setStatus ] = useState('')
- const { id } = useParams()
- const clients = useSelector((state) => state.clients.clients)
- const { invoice } = useSelector((state) => state.invoices);
- const dispatch = useDispatch()
- const history = useHistory()
- const user = JSON.parse(localStorage.getItem('profile'))
-
-
- useEffect(() => {
- getTotalCount()
- // eslint-disable-next-line
- },[location])
-
-
- const getTotalCount = async() => {
- try {
- const response = await axios.get(`${process.env.REACT_APP_API}/invoices/count?searchQuery=${user?.result?._id}`);
- // console.log(response.data);
- //Get total count of invoice from the server and increment by one to serialized numbering of invoice
- setInvoiceData({...invoiceData, invoiceNumber: (Number(response.data) + 1).toString().padStart(3, '0')})
- } catch (error) {
- console.error(error);
+ useEffect(() => {
+ if (type === "Receipt") {
+ setStatus("Paid");
+ } else {
+ setStatus("Unpaid");
+ }
+ }, [type]);
+
+ const defaultProps = {
+ options: currencies,
+ getOptionLabel: (option) => option.label,
+ };
+
+ const clientsProps = {
+ options: clients,
+ getOptionLabel: (option) => option.name,
+ };
+
+ const handleDateChange = (date) => {
+ setSelectedDate(date);
+ };
+
+ const handleRates = (e) => {
+ setRates(e.target.value);
+ setInvoiceData((prevState) => ({ ...prevState, tax: e.target.value }));
+ };
+
+ // console.log(invoiceData)
+ // Change handler for dynamically added input field
+ const handleChange = (index, e) => {
+ const values = [...invoiceData.items];
+ values[index][e.target.name] = e.target.value;
+ setInvoiceData({ ...invoiceData, items: values });
+ };
+
+ useEffect(() => {
+ //Get the subtotal
+ const subTotal = () => {
+ var arr = document.getElementsByName("amount");
+ var subtotal = 0;
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i].value) {
+ subtotal += +arr[i].value;
}
+ // document.getElementById("subtotal").value = subtotal;
+ setSubTotal(subtotal);
}
-
-
-
-
- useEffect(() => {
- dispatch(getInvoice(id));
- // eslint-disable-next-line
- }, [id]);
-
- useEffect(() => {
- dispatch(getClientsByUser({search: user?.result._id || user?.result?.googleId}));
- // eslint-disable-next-line
- }, [dispatch]);
-
-
- useEffect(() => {
- if(invoice) {
- //Automatically set the default invoice values as the ones in the invoice to be updated
- setInvoiceData(invoice)
- setRates(invoice.rates)
- setClient(invoice.client)
- setType(invoice.type)
- setStatus(invoice.status)
- setSelectedDate(invoice.dueDate)
- }
- }, [invoice])
-
-
- useEffect(() => {
- if(type === 'Receipt') {
- setStatus('Paid')
- } else {
- setStatus('Unpaid')
- }
- },[type])
-
- const defaultProps = {
- options: currencies,
- getOptionLabel: (option) => option.label
- };
-
- const clientsProps = {
- options: clients,
- getOptionLabel: (option) => option.name
- };
-
-
- const handleDateChange = (date) => {
- setSelectedDate(date);
};
- const handleRates =(e) => {
- setRates(e.target.value)
- setInvoiceData((prevState) => ({...prevState, tax: e.target.value}))
- }
+ subTotal();
+ }, [invoiceData]);
- // console.log(invoiceData)
- // Change handler for dynamically added input field
- const handleChange =(index, e) => {
- const values = [...invoiceData.items]
- values[index][e.target.name] = e.target.value
- setInvoiceData({...invoiceData, items: values})
-
- }
-
- useEffect(() => {
- //Get the subtotal
- const subTotal =()=> {
- var arr = document.getElementsByName("amount");
- var subtotal = 0;
- for(var i = 0; i < arr.length; i++) {
- if(arr[i].value) {
- subtotal += +arr[i].value;
- }
- // document.getElementById("subtotal").value = subtotal;
- setSubTotal(subtotal)
- }
- }
-
- subTotal()
-
- }, [invoiceData])
-
-
- useEffect(() => {
- const total =() => {
-
- //Tax rate is calculated as (input / 100 ) * subtotal + subtotal
- const overallSum = rates /100 * subTotal + subTotal
- //VAT is calculated as tax rates /100 * subtotal
- setVat(rates /100 * subTotal)
- setTotal(overallSum)
-
-
- }
- total()
- }, [invoiceData, rates, subTotal])
-
-
- const handleAddField = (e) => {
- e.preventDefault()
- setInvoiceData((prevState) => ({...prevState, items: [...prevState.items, {itemName: '', unitPrice: '', quantity: '', discount: '', amount: '' }]}))
- }
-
- const handleRemoveField =(index) => {
- const values = invoiceData.items
- values.splice(index, 1)
- setInvoiceData((prevState) => ({...prevState, values}))
- // console.log(values)
- }
-
-
- console.log(invoiceData)
-
- const handleSubmit = async (e ) => {
- e.preventDefault()
- if(invoice) {
- dispatch(updateInvoice( invoice._id, {
- ...invoiceData,
- subTotal: subTotal,
- total: total,
- vat: vat,
- rates: rates,
- currency: currency,
- dueDate: selectedDate,
- client,
- type: type,
- status: status
- }))
- history.push(`/invoice/${invoice._id}`)
- } else {
-
- dispatch(createInvoice({
- ...invoiceData,
- subTotal: subTotal,
- total: total,
- vat: vat,
- rates: rates,
- currency: currency,
- dueDate: selectedDate,
+ useEffect(() => {
+ const total = () => {
+ //Tax rate is calculated as (input / 100 ) * subtotal + subtotal
+ const overallSum = (rates / 100) * subTotal + subTotal;
+ //VAT is calculated as tax rates /100 * subtotal
+ setVat((rates / 100) * subTotal);
+ setTotal(overallSum);
+ };
+ total();
+ }, [invoiceData, rates, subTotal]);
+
+ const handleAddField = (e) => {
+ e.preventDefault();
+ setInvoiceData((prevState) => ({
+ ...prevState,
+ items: [
+ ...prevState.items,
+ { itemName: "", unitPrice: "", quantity: "", discount: "", amount: "" },
+ ],
+ }));
+ };
+
+ const handleRemoveField = (index) => {
+ const values = invoiceData.items;
+ values.splice(index, 1);
+ setInvoiceData((prevState) => ({ ...prevState, values }));
+ // console.log(values)
+ };
+
+ // console.log(invoiceData)
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ if (invoice) {
+ dispatch(
+ updateInvoice(invoice._id, {
+ ...invoiceData,
+ subTotal: subTotal,
+ total: total,
+ vat: vat,
+ rates: rates,
+ currency: currency,
+ dueDate: selectedDate,
+ client,
+ type: type,
+ status: status,
+ })
+ );
+ history.push(`/invoice/${invoice._id}`);
+ } else {
+ dispatch(
+ createInvoice(
+ {
+ ...invoiceData,
+ subTotal: subTotal,
+ total: total,
+ vat: vat,
+ rates: rates,
+ currency: currency,
+ dueDate: selectedDate,
invoiceNumber: `${
- invoiceData.invoiceNumber < 100 ?
- (Number(invoiceData.invoiceNumber)).toString().padStart(3, '0')
+ invoiceData.invoiceNumber < 100
+ ? Number(invoiceData.invoiceNumber).toString().padStart(3, "0")
: Number(invoiceData.invoiceNumber)
}`,
- client,
- type: type,
- status: status,
- paymentRecords: [],
- creator: [user?.result?._id || user?.result?.googleId] },
- history
- ))
- }
-
- // setInvoiceData(initialState)
+ client,
+ type: type,
+ status: status,
+ paymentRecords: [],
+ creator: [user?.result?._id || user?.result?.googleId],
+ },
+ history
+ )
+ );
}
- const classes = useStyles()
- const [open, setOpen] = useState(false);
+ // setInvoiceData(initialState)
+ };
- const CustomPaper = (props) => {
- return