In my project I am wanted to update my total stock and sold out amount of a product whenever user order a product and after that if the seller updated the status to delivered then the stock and sold out amount should update accordingly. Though the status is updating successfully but the sold out and stock amount is not updating. So I need your help to overcome this issue. I am also adding the relevant code.
Thanks in advance
OrderDetails.jsx:
import React, { useEffect, useState } from "react";
import styles from "../../styles/styles";
import { BsFillBagFill } from "react-icons/bs";
import { Link, useNavigate, useParams } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { getAllOrdersOfShop } from "../../redux/actions/orderAction";
import { backend_url, server } from "../../server";
import axios from "axios";
import { toast } from "react-toastify";
const OrderDetails = () => {
const { orders, isLoading } = useSelector((state) => state.order);
const { seller } = useSelector((state) => state.seller);
const dispatch = useDispatch();
const [status, setStatus] = useState("");
const navigate = useNavigate();
const { id } = useParams();
useEffect(() => {
dispatch(getAllOrdersOfShop(seller._id));
}, [dispatch]);
const data = orders && orders.find((item) => item._id === id);
const orderUpdateHandler = async (e) => {
await axios
.put(
`${server}/order/update-order-status/${id}`,
{
status,
},
{ withCredentials: true }
)
.then((res) => {
toast.success("Order updated!");
navigate("/dashboard-orders");
})
.catch((error) => {
toast.error(error.response.data.message);
});
};
const refundOrderUpdateHandler = async (e) => {
await axios
.put(
`${server}/order/order-refund-success/${id}`,
{
status,
},
{ withCredentials: true }
)
.then((res) => {
toast.success("Order updated!");
dispatch(getAllOrdersOfShop(seller._id));
})
.catch((error) => {
toast.error(error.response.data.message);
});
};
console.log(data?.status);
return (
<div className={`py-4 min-h-screen ${styles.section}`}>
<div className="flex items-center justify-between w-full">
<div className="flex items-center">
<BsFillBagFill size={30} color="crimson" />
<h1 className="pl-2 text-[25px]">Order Details</h1>
</div>
<Link to="/dashboard-orders">
<div
className={`${styles.button} !bg-[#fce1e6] !rounded-[4px] text-[#e94560] font-[600] !h-[45px] text-[18px]`}
>
Order List
</div>
</Link>
</div>
<div className="flex items-center justify-between w-full pt-6">
<h5 className="text-[#00000084]">
Order ID: <span>#{data?._id?.slice(0, 8)}</span>
</h5>
<h5 className="text-[#00000084]">
Placed on: <span>{data?.createdAt?.slice(0, 10)}</span>
</h5>
</div>
{/* order items */}
<br />
<br />
{data &&
data?.cart.map((item, index) => (
<div className="flex items-start w-full mb-5" key={index}>
<img
src={`${backend_url}/${item.images[0]}`}
alt=""
className="w-[80x] h-[80px]"
/>
<div className="w-full">
<h5 className="pl-3 text-[20px]">{item.name}</h5>
<h5 className="pl-3 text-[20px] text-[#00000091]">
US${item.discountPrice} x {item.qty}
</h5>
</div>
</div>
))}
<div className="w-full text-right border-t">
<h5 className="pt-3 text-[18px]">
Total Price: <strong>US${data?.totalPrice}</strong>
</h5>
</div>
<br />
<br />
<div className="items-center w-full 800px:flex">
<div className="w-full 800px:w-[60%]">
<h4 className="pt-3 text-[20px] font-[600]">Shipping Address:</h4>
<h4 className="pt-3 text-[20px]">
{data?.shippingAddress.address1 +
" " +
data?.shippingAddress.address2}
</h4>
<h4 className=" text-[20px]">{data?.shippingAddress.country}</h4>
<h4 className=" text-[20px]">{data?.shippingAddress.city}</h4>
<h4 className=" text-[20px]">{data?.user?.phoneNumber}</h4>
</div>
<div className="w-full 800px:w-[40%]">
<h4 className="pt-3 text-[20px]">Payment Info:</h4>
<h4>
Status:{" "}
{data?.paymentInfo?.status ? data?.paymentInfo?.status : "Not Paid"}
</h4>
</div>
</div>
<br />
<br />
<h4 className="pt-3 text-[20px] font-[600]">Order Status:</h4>
{data?.status !== "Processing refund" &&
data?.status !== "Refund Success" && (
<select
value={status}
onChange={(e) => setStatus(e.target.value)}
className="w-[200px] mt-2 border h-[35px] rounded-[5px]"
>
{[
"Processing",
"Transferred to delivery partner",
"Shipping",
"Received",
"On the way",
"Delivered",
]
.slice(
[
"Processing",
"Transferred to delivery partner",
"Shipping",
"Received",
"On the way",
"Delivered",
].indexOf(data?.status)
)
.map((option, index) => (
<option value={option} key={index}>
{option}
</option>
))}
</select>
)}
{data?.status === "Processing refund" ||
data?.status === "Refund Success" ? (
<select
value={status}
onChange={(e) => setStatus(e.target.value)}
className="w-[200px] mt-2 border h-[35px] rounded-[5px]"
>
{["Processing refund", "Refund Success"]
.slice(
["Processing refund", "Refund Success"].indexOf(data?.status)
)
.map((option, index) => (
<option value={option} key={index}>
{option}
</option>
))}
</select>
) : null}
<div
className={`${styles.button} mt-5 !bg-[#FCE1E6] !rounded-[4px] text-[#E94560] font-[600] !h-[45px] text-[18px]`}
onClick={
data?.status !== "Processing refund"
? orderUpdateHandler
: refundOrderUpdateHandler
}
>
Update Status
</div>
</div>
);
};
export default OrderDetails;
Mainly the problem is in the "refundOrderUpdateHandler" and "orderUpdateHandler" function of the OrderDetails.jsx.
controller.js:
// update order status for seller
router.put(
"/update-order-status/:id",
isSeller,
catchAsyncErrors(async (req, res, next) => {
try {
const order = await Order.findById(req.params.id);
if (!order) {
return next(new ErrorHandler("Order not found with this id", 400));
}
if (req.body.status === "Transferred to delivery partner") {
order.cart.forEach(async (o) => {
await updateOrder(o._id, o.qty);
});
}
order.status = req.body.status;
if (req.body.status === "Delivered") {
order.deliveredAt = Date.now();
order.paymentInfo.status = "Succeeded";
const serviceCharge = order.totalPrice * 0.1;
await updateSellerInfo(order.totalPrice - serviceCharge);
}
await order.save({ validateBeforeSave: false });
res.status(200).json({
success: true,
order,
});
async function updateOrder(id, qty) {
const product = await Product.findById(id);
product.stock -= qty;
product.sold_out += qty;
await product.save({ validateBeforeSave: false });
}
async function updateSellerInfo(amount) {
const seller = await Shop.findById(req.seller.id);
seller.availableBalance = amount;
await seller.save();
}
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
})
);
// accept the refund ---- seller
router.put(
"/order-refund-success/:id",
isSeller,
catchAsyncErrors(async (req, res, next) => {
try {
const order = await Order.findById(req.params.id);
if (!order) {
return next(new ErrorHandler("Order not found with this id", 400));
}
order.status = req.body.status;
await order.save();
res.status(200).json({
success: true,
message: "Order Refund successfull!",
});
if (req.body.status === "Refund Success") {
order.cart.forEach(async (o) => {
await updateOrder(o._id, o.qty);
});
}
async function updateOrder(id, qty) {
const product = await Product.findById(id);
product.stock += qty;
product.sold_out -= qty;
await product.save({ validateBeforeSave: false });
}
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
})
);
2
Answers
if you want show realtime stock after update ,
after your are get new data for stock or other , update order state agin .
this state :
i hope this help .
To update them, you need to first retrieve the relevant product from your database based on the product ID in the order. Then you can update the stock and sold out amount of the product based on the quantity ordered and the status of the order.
Here’s one way to update the stock and sold out amount in your code:
Import the updateProduct action from your Redux actions file.
Update the stock and sold out amount of the product based on the quantity ordered and the status of the order.
Here’s the updated orderUpdateHandler function with the changes:
Note: This assumes that your updateProduct action updates the stock and sold fields in your database.
if this not working , message me this telegram : https://t.me/Mohi_ABa