Home > other >  post request with status 400
post request with status 400

Time:05-02

I have this project, and as it is clear in the postman, I have a request, and through the request, I must send the identification number of the invoice, and the identification number of the user must be sent, in addition to a message, but the real problem is that I did not know how to get the identification number of the user, in addition to The request did not work, with the case of 400, which means that there is a problem with the function that communicates with the backend

and in Network i have this errors:

enter image description here enter image description here enter image description here

how can i solve my problem?

enter image description here

invoiceSlice.js:

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
import FuseUtils from "@fuse/utils";
import { getInvoices } from "./invoicesSlice";

export const assignToUser = createAsyncThunk(
  "invoicesApp/invoice/assignToUser",
  async ({ invoiceId, userId, message }, { dispatch }) => {
    console.log("invoiceId, userId, message", invoiceId, userId, message);
    const response = await axios
      .post(`/invoices/flow/${invoiceId}/approve`, { userId, message })
      .catch((error) => {
        console.log("error response: ", error);
      });
    const data = await response.data.data;
    console.log("approve invoices: ", data);
    dispatch(getInvoices());
    return data;
  }
);

const invoiceSlice = createSlice({
  name: "invoicesApp/invoice",
  initialState: null,
  reducers: {
    resetInvoice: () => null,
    newInvoice: {
      reducer: (state, action) => action.payload,
      prepare: (event) => ({
        payload: {
          invoice: "",
          netAmount: 0,
          taxNumber: 0,
          grossAmount: 0,
          dueDate: "",
          issueDate: "",
        },
      }),
    },
  },
  extraReducers: {
    [assignToUser.fulfilled]: (state, action) => action.payload,
  },
});

export const { newInvoice, resetInvoice } = invoiceSlice.actions;

export default invoiceSlice.reducer;

approveUser.js:

import { Fragment, useState } from "react";
import { ButtonGroup } from "@material-ui/core";
import React from "react";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { useTheme } from "@material-ui/core/styles";
import { useSnackbar } from "notistack";
import Slide from "@material-ui/core/Slide";
import {
  rejectInvoice,
  approveInvoice,
  assignToUser,
} from "../../store/invoiceSlice";
import { useDispatch, useSelector } from "react-redux";
import TextField from "@mui/material/TextField";
import FlagIcon from "@mui/icons-material/Flag";
import { makeStyles } from "@material-ui/core/styles";
import Autocomplete from "@mui/material/Autocomplete";
import { getUsers } from "../../store/invoiceSlice";
import { useEffect } from "react";

const useStyles = makeStyles((theme) => ({
  paper: { padding: "3rem", maxWidth: "990px", minWidth: "300px" },
  textStyle: {
    paddingLeft: "2rem",
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 120,
  },
  selectEmpty: {
    marginTop: theme.spacing(2),
  },
  font: {
    fontSize: "5rem",
  },
}));

const GroupButttonApproveStatus = (id) => {
  const [dialogOpen, setDialogOpen] = useState(false);
  const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
  const [assignToUserDialog, setAssignToUserDialog] = useState(false);
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const dispatch = useDispatch();
  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
  const AssignToUserFullScreen = useMediaQuery(theme.breakpoints.down("md"));
  const classes = useStyles();

  const [users, setUsers] = useState([]);
  const [message, setMessage] = useState("");

  useEffect(() => {
    getUsers().then((response) => {
      setUsers(response);
    });
  }, []);
  // confirm

  console.log("users: ", users);

  const handleAssignToUserDialogOpen = () => {
    setAssignToUserDialog(true);
  };

  const handleAssignToUserDialogClose = () => setAssignToUserDialog(false);
  //   end assign to user
  const handleConfirmDialogClose = () => setConfirmDialogOpen(false);
  const handleClickConfirmDialogOpen = () => {
    setConfirmDialogOpen(true);
  };

  //end confirm

  const handleDialogClose = () => setDialogOpen(false);
  const handleClickOpen = () => {
    setDialogOpen(true);
  };

  const handleClose = () => {
    setDialogOpen(false);
  };

  const rejectInvoiceHandleClick = () => {
    enqueueSnackbar(
      "Invoice rejected successfully",
      { variant: "error" },
      {
        anchorOrigin: {
          vertical: "top",
          horizontal: "right",
        },
      },
      { TransitionComponent: Slide }
    );
  };

  const approveInvoiceHandleClick = () => {
    enqueueSnackbar(
      "Invoice approved successfully",
      { variant: "success" },
      {
        anchorOrigin: {
          vertical: "top",
          horizontal: "right",
        },
      },
      { TransitionComponent: Slide }
    );
  };
  return (
    <Fragment>
      <ButtonGroup size="large">
        <Button
          onClick={(ev) => {
            handleClickConfirmDialogOpen();
          }}
        >
          Approve
        </Button>
        <Button
          onClick={(ev) => {
            handleClickOpen();
          }}
        >
          Reject
        </Button>
        <Button
          onClick={(ev) => {
            handleAssignToUserDialogOpen();
          }}
        >
          Assign to User to approve
        </Button>
      </ButtonGroup>
      {/* reject Dialog */}
      <Dialog
        classes={{ paper: classes.paper }}
        maxWidth="sm"
        fullScreen={fullScreen}
        open={dialogOpen}
        onClose={handleDialogClose}
      >
        <DialogTitle style={{ fontWeight: "bold" }}>Reject Invoice</DialogTitle>
        <DialogContent>
          <div
            style={{
              backgroundColor: "#F8F9FA",
              borderRadius: 10,
              padding: "3rem",
            }}
          >
            <DialogContentText>
              <FlagIcon
                style={{ fontSize: 40, color: "#dc3c24", paddingRight: "1rem" }}
              />
              Do you really want to reject this invoice ?
            </DialogContentText>
            <DialogContentText>
              <FlagIcon
                style={{ fontSize: 40, color: "#F8F9FA", paddingRight: "1rem" }}
              />
              Keep in mind that once the invoice is rejected you won’t be able
              to proceed with it.
            </DialogContentText>
          </div>
        </DialogContent>
        <DialogActions>
          <div style={{ paddingRight: "1rem" }}>
            <Button
              onClick={handleClose}
              style={{ color: "#dc3c24", fontWeight: 500 }}
              autoFocus
            >
              Cancel
            </Button>
            <Button
              onClick={(ev) => {
                dispatch(rejectInvoice(id?.id));
                rejectInvoiceHandleClick(ev);
                handleClose();
              }}
              style={{ color: "#212529", fontWeight: 500 }}
              color="primary"
              autoFocus
            >
              Reject Invoice
            </Button>
          </div>
        </DialogActions>
      </Dialog>

      {/* End reject Dialog */}

      {/* Confirm Dialog */}
      <Dialog
        classes={{ paper: classes.paper }}
        maxWidth="sm"
        fullScreen={fullScreen}
        open={confirmDialogOpen}
        onClose={handleConfirmDialogClose}
      >
        <DialogTitle style={{ fontWeight: "bold" }}>
          Approve Invoice
        </DialogTitle>
        <DialogContent>
          <div
            style={{
              backgroundColor: "#F8F9FA",
              borderRadius: 10,
              padding: "3rem",
            }}
          >
            <DialogContentText>Almost ready for payment !</DialogContentText>
            <DialogContentText>
              By confirming you mark this invoice ready for approval.
            </DialogContentText>
          </div>
        </DialogContent>
        <DialogActions>
          <div style={{ paddingRight: "1rem" }}>
            <Button
              onClick={handleConfirmDialogClose}
              style={{ color: "#dc3c24", fontWeight: 500 }}
              autoFocus
            >
              Cancel
            </Button>
            <Button
              onClick={(ev) => {
                dispatch(approveInvoice(id?.id));
                approveInvoiceHandleClick(ev);
                handleConfirmDialogClose();
              }}
              style={{ color: "#212529", fontWeight: 500 }}
              color="primary"
              autoFocus
            >
              yes, Confirm
            </Button>
          </div>
        </DialogActions>
      </Dialog>

      {/* End Confirm Dialog */}

      {/* assign to user dialog */}

      <Dialog
        classes={{ paper: classes.paper }}
        maxWidth="sm"
        fullScreen={AssignToUserFullScreen}
        open={assignToUserDialog}
        onClose={handleAssignToUserDialogClose}
      >
        <DialogTitle style={{ fontWeight: "bold", fontSize: "3rem" }}>
          Request approval
        </DialogTitle>
        <div
          style={{
            backgroundColor: "#F8F9FA",
            borderRadius: 10,
            padding: "2rem",
            paddingLeft: "2rem",
          }}
        >
          <DialogContentText style={{ fontWeight: 600 }}>
            {" "}
            <FlagIcon
              style={{ fontSize: 40, color: "#aacc00", paddingRight: "1rem" }}
            />
            Send an invoice approval request to a team member.
          </DialogContentText>
          <DialogContentText style={{ paddingLeft: 10 }}>
            The assigned member will receive a notification asking them to
            approve this invoice. Once they accept, payment is on the way!
          </DialogContentText>
        </div>

        <DialogTitle>Assign a member to approve</DialogTitle>
        <DialogContent>
          <Autocomplete
            id="combo-box-demo"
            // value={users || ""}
            options={users || []}
            getOptionLabel={(option) => option.name || ""}
            sx={{ width: 860 }}
            renderInput={(params) => (
              <TextField
                {...params}
                placeholder="Search Member"
                fullWidth
                InputProps={{ ...params.InputProps, style: { fontSize: 17 } }}
                InputLabelProps={{ style: { fontSize: 17 } }}
              />
            )}
          />
        </DialogContent>
        <DialogContent style={{ marginTop: "15rem" }}>
          <form className={classes.root} noValidate autoComplete="off">
            <TextField
              value={message}
              onChange={(e) => setMessage(e.target.value)}
              id="outlined-basic"
              variant="outlined"
              placeholder="Add a message"
              fullWidth
              size="medium"
              InputProps={{ style: { fontSize: 17 } }}
              InputLabelProps={{ style: { fontSize: 17 } }}
            />
          </form>
        </DialogContent>
        <DialogActions>
          <div style={{ paddingRight: "1rem" }}>
            <Button
              onClick={handleAssignToUserDialogClose}
              style={{ color: "#dc3c24", fontWeight: 500 }}
              autoFocus
            >
              Cancel
            </Button>
            <Button
              onClick={(ev) => {
                dispatch(assignToUser(id?.id, users.id, message));
                approveInvoiceHandleClick(ev);
                handleAssignToUserDialogClose();
              }}
              style={{ color: "#212529", fontWeight: 500 }}
              color="primary"
              autoFocus
            >
              Assign to approve
            </Button>
          </div>
        </DialogActions>
      </Dialog>
    </Fragment>
  );
};

export default GroupButttonApproveStatus;

invoiceDetails.js:

import React from "react";
import { getInvoice } from "../../store/invoiceSlice";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import Grid from "@material-ui/core/Grid";
import TextField from "@material-ui/core/TextField";
import moment from "moment";
import InputAdornment from "@material-ui/core/InputAdornment";
import TodayIcon from "@material-ui/icons/Today";
import { makeStyles } from "@material-ui/core/styles";
import RejectDialog from "./rejectDialog";
import GroupButton from "./groupButttonReviewStatus";
import GroupButttonReviewStatus from "./groupButttonReviewStatus";
import GroupButttonApproveStatus from "./groupButtonApproveStatus";
import GroupButttonPaymentStatus from "./groupButtonPaymentStatus";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { useTheme } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
  root: {
    "& > *": {
      margin: theme.spacing(1),
    },
  },
  input: {
    display: "none",
  },
  button: {
    margin: theme.spacing(1),
    // padding: theme.spacing(4),
  },
}));

const InvoiceDetails = () => {
  const classes = useStyles();
  const theme = useTheme();
  const routeParams = useParams();
  const [invoice, setInvoice] = useState([]);
  const [open, setOpen] = React.useState(false);
  const anchorRef = React.useRef(null);
  const [selectedIndex, setSelectedIndex] = React.useState(1);
  const breakpoint = useMediaQuery(theme.breakpoints.down("sm"));
  // const defaultLayoutPluginInstance = defaultLayoutPlugin();

  useEffect(() => {
    getInvoice(routeParams).then((response) => {
      setInvoice(response);
    });
  }, []);

  const handleClick = () => {
    console.info(`You clicked ${options[selectedIndex]}`);
  };

  const handleMenuItemClick = (event, index) => {
    setSelectedIndex(index);
    setOpen(false);
  };

  const handleToggle = () => {
    setOpen((prevOpen) => !prevOpen);
  };

  const handleClose = (event) => {
    if (anchorRef.current && anchorRef.current.contains(event.target)) {
      return;
    }

    setOpen(false);
  };

  console.log("invoice url: ", invoice?.file?.url);
  console.log("invoice tara : ", invoice);

  const statusGropButton = (status, id) => {
    switch (status) {
      case "review_pending":
        return <GroupButttonReviewStatus id={id} />;
      case "approval_pending":
        return <GroupButttonApproveStatus id={id} />;
      case "payment_pending":
        return <GroupButttonPaymentStatus id={id} />;
      case "rejected":
        return <GroupButton id={id} />;
      default:
        return;
    }
  };

  return (
    <>
      <Grid container>
        <Grid item xs={7} sm={7}>
          {/* pdf viewer */}
          <object
            // data={invoice?.file?.url}
            data="https://documentcloud.adobe.com/view-sdk-demo/PDFs/Bodea Brochure.pdf"
            type="application/pdf"
            width="100%"
            height="100%"
          >
            <p>
              Alternative text - include a link{" "}
              <a href="https://documentcloud.adobe.com/view-sdk-demo/PDFs/Bodea Brochure.pdf">
                to the PDF!
              </a>
            </p>
          </object>
        </Grid>

        <Grid item xs={5} sm={5} style={{ padding: "4rem" }}>
          <Grid item>
            <h1 style={{ fontWeight: "bold" }}>Invoice Details</h1>
          </Grid>

          <Grid item style={{ marginTop: "3rem", marginBottom: "2rem" }}>
            <Grid item style={{ marginBottom: 10 }}>
              <h3>From</h3>
            </Grid>
            <Grid item>
              <h3>{invoice?.submittedBy?.name || ""}</h3>
            </Grid>
            <Grid item>
              <h3>{invoice?.submittedBy?.email || ""}</h3>
            </Grid>
          </Grid>

          <Grid item>
            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Invoice ID</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  id="outlined-size-normal"
                  value={invoice.id || ""}
                  variant="outlined"
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Issue Date</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  id="outlined-size-normal"
                  value={
                    moment(moment.utc(invoice.issueDate).toDate())
                      .local()
                      .format("YYYY-MM-DD HH:mm:ss") || ""
                  }
                  variant="outlined"
                  InputProps={{
                    endAdornment: (
                      <InputAdornment position="start">
                        <TodayIcon />
                      </InputAdornment>
                    ),
                  }}
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Due Date</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  id="outlined-size-normal"
                  value={
                    moment(moment.utc(invoice.dueDate).toDate())
                      .local()
                      .format("YYYY-MM-DD HH:mm:ss") || ""
                  }
                  variant="outlined"
                  InputProps={{
                    endAdornment: (
                      <InputAdornment position="start">
                        <TodayIcon />
                      </InputAdornment>
                    ),
                  }}
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Net Amount</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  id="outlined-size-normal"
                  value={invoice.netAmount || ""}
                  variant="outlined"
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Tax Number</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  id="outlined-size-normal"
                  value={invoice.taxNumber || ""}
                  variant="outlined"
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid container item direction={breakpoint ? "row" : "column"}>
              <Grid
                container
                item
                xs={3}
                sm={3}
                direction="row"
                justifyContent="flex-start"
                alignItems="center"
              >
                <h3>Gross Amount</h3>
              </Grid>
              <Grid item xs={12} sm={12}>
                <TextField
                  className="mt-8 mb-16"
                  // label="Size"
                  id="outlined-size-normal"
                  value={invoice.grossAmount || ""}
                  variant="outlined"
                  fullWidth
                />
              </Grid>
            </Grid>

            <Grid
              container
              direction="row"
              justifyContent="center"
              alignItems="center"
              style={{ marginTop: "3rem" }}
            >
              <Grid item>{statusGropButton(invoice.status, invoice?.id)}</Grid>
            </Grid>
          </Grid>
        </Grid>
      </Grid>
    </>
  );
};

export default InvoiceDetails;

CodePudding user response:

Based on your code I observed this.

  • You are already passing invoice?.id in statusGropButton(invoice.status, invoice?.id) method.
  • You are again expecting id from the input as id?.id in assignToUser(id?.id, users.id, message). Why?

Just assuming, because of that the invoiceId is going as undefined. Try by passing just id instead of id?.id while calling the api functions.

CodePudding user response:

invoiceId undefined when send request ,you could check assignToUser

  • Related