diff --git a/resources/Orders/PosCheckoutController.js b/resources/Orders/PosCheckoutController.js new file mode 100644 index 0000000..7792e1f --- /dev/null +++ b/resources/Orders/PosCheckoutController.js @@ -0,0 +1,186 @@ +import { shippingAddress } from "../ShippingAddresses/ShippingAddressModel.js"; +import { Order } from "./orderModel.js"; + +//generate unique order id +const generateUniqueOrderId = async () => { + const currentYear = new Date().getFullYear(); + // Find the latest order to get the last serial number + const latestOrder = await Order.findOne({}, {}, { sort: { orderID: -1 } }); + let serialNumber = 1; + + if (latestOrder) { + const lastYear = parseInt(latestOrder.orderID.substring(0, 4), 10); + if (lastYear === currentYear) { + // If the last order was in the current year, increment the serial number + serialNumber = parseInt(latestOrder.orderID.substring(4), 10) + 1; + } + } + // Pad the serial number with zeros and concatenate with the current year + const paddedSerialNumber = serialNumber.toString().padStart(7, "0"); + const orderId = `${currentYear}${paddedSerialNumber}`; + return orderId; +}; + +// export const poscreateOrderCheckout = async (req, res) => { +// try { +// const { userr,address, cart, subtotal,orderType } = req.body; +// // console.log(req.body) +// // Perform validation +// if (cart.length < 1) +// return res.status(400).json({ message: "cart is empty!" }); +// if (!address) +// return res +// .status(404) +// .json({ message: "please select shipping address!" }); +// if (!subtotal) +// return res +// .status(404) +// .json({ message: "please provide product subtotal!" }); +// if (!userr) +// return res.status(400).json({ message: "user is not defined" }); + +// // Retrieve shipping address from database +// let addss = await shippingAddress.findById(address); + +// let shipping = { +// first_Name: addss.first_Name, +// last_Name: addss?.last_Name, +// phone_Number: addss?.phone_Number, +// street: addss?.street, +// city: addss?.city, +// state: addss?.state, +// postalCode: addss?.postalCode, +// country: addss?.country, +// company_name: addss?.company_name, +// gst_number: addss?.gst_number, +// addressId: address, +// }; + +// // Construct order items array +// const orderItems = await cart.map((item) => ({ +// product: item.product._id, +// name: item.product.name, +// variant_Name: item.variant.variant_Name, +// price: Number(item.variant.price), +// total_price: item.quantity * Number(item.variant.price), + +// image: item.product.image, +// quantity: item.quantity, +// gst_amount: Number( +// (Number(item.variant.price) * item.variant.gst_Id?.tax) / 100 +// )?.toFixed(3), +// total_gst_amount: Number( +// Number(item.quantity) * +// Number( +// (Number(item.variant.price) * item.variant.gst_Id?.tax) / 100 +// ) +// )?.toFixed(3), +// gst_rate: item.variant.gst_Id?.tax, +// tax_Name: item.variant?.gst_Id?.name, +// product_Subtotal: Number( +// Number(item.quantity * Number(item.variant.price)) + +// Number( +// Number(item.quantity) * +// Number( +// (Number(item.variant.price) * item.variant.gst_Id?.tax) / 100 +// ) +// ) +// ).toFixed(3), +// })); + +// // Generate a unique order ID +// const Id = await generateUniqueOrderId(); + +// // Create the order document +// const order = await Order.create({ +// orderID: Id, +// total_amount: subtotal, +// orderItems, +// shippingInfo: shipping, +// user: userr, +// orderType, +// paymentMode:"cod", +// payment_status:"success", +// isPaid:true, +// paidAt:new Date().toISOString(), +// }); + +// return res.status(201).json({ success: true, order }); +// } catch (error) { +// console.error("Error creating order:", error); +// return res +// .status(500) +// .json({ success: false, message: "Internal server error" }); +// } +// }; + +export const poscreateOrderCheckout = async (req, res) => { + try { + const { userr, address, cart, subtotal, orderType } = req.body; + + // Perform validation + if (cart.length < 1) + return res.status(400).json({ message: "Cart is empty!" }); + if (!address) + return res.status(404).json({ message: "Please select a shipping address!" }); + if (!subtotal) + return res.status(404).json({ message: "Please provide the product subtotal!" }); + if (!userr) + return res.status(400).json({ message: "User is not defined" }); + + // Retrieve shipping address from database + let addss = await shippingAddress.findById(address); + + let shipping = { + first_Name: addss.first_Name, + last_Name: addss?.last_Name, + phone_Number: addss?.phone_Number, + street: addss?.street, + city: addss?.city, + state: addss?.state, + postalCode: addss?.postalCode, + country: addss?.country, + company_name: addss?.company_name, + gst_number: addss?.gst_number, + addressId: address, + }; + + // Construct order items array + const orderItems = cart.map((item) => ({ + product: item.product._id, + name: item.product.name, + variant_Name: item.variant.variant_Name, + price: Number(item.variant.price), + total_price: item.quantity * Number(item.variant.price), + image: item.product.image, + quantity: item.quantity, + gst_amount: Number((Number(item.variant.price) * item.variant.gst_Id?.tax) / 100)?.toFixed(3), + total_gst_amount: Number(Number(item.quantity) * Number((Number(item.variant.price) * item.variant.gst_Id?.tax) / 100))?.toFixed(3), + gst_rate: item.variant.gst_Id?.tax, + tax_Name: item.variant?.gst_Id?.name, + product_Subtotal: Number(Number(item.quantity * Number(item.variant.price)) + Number(Number(item.quantity) * Number((Number(item.variant.price) * item.variant.gst_Id?.tax) / 100))).toFixed(3), + })); + + // Generate a unique order ID + const Id = await generateUniqueOrderId(); + + // Create the order document + const order = await Order.create({ + orderID: Id, + total_amount: subtotal, + orderItems, + shippingInfo: shipping, + user: userr, + orderType, + paymentMode: "cod", + payment_status: "success", + isPaid: true, + paidAt: new Date().toISOString(), + }); + + return res.status(201).json({ success: true, order }); + } catch (error) { + console.error("Error creating order:", error); + return res.status(500).json({ success: false, message: "Internal server error" }); + } +}; diff --git a/resources/Orders/RazerPayCheckoutController.js b/resources/Orders/RazerPayCheckoutController.js index 5211a0e..7af902c 100644 --- a/resources/Orders/RazerPayCheckoutController.js +++ b/resources/Orders/RazerPayCheckoutController.js @@ -31,6 +31,8 @@ const generateUniqueOrderId = async () => { export const getRzpkey = async (req, res) => { const { name, email } = req.user; + // console.log(name); + // console.log(email); res.status(200).json({ success: true, key: process.env.RAZERPAY_KEY_ID, @@ -38,9 +40,35 @@ export const getRzpkey = async (req, res) => { email, }); }; +//point of sale order +export const getRazerpayKey = async (req, res) => { + try { + const { name, email } = req.params; + // console.log("name", name, "email", email); + if (!name || !email) { + throw new Error("Name and email are required parameters"); + } + res.status(200).json({ + success: true, + key: process.env.RAZERPAY_KEY_ID, + name, + email, + }); + } catch (error) { + console.error("Error in getRzpKey:", error); + res + .status(500) + .json({ + success: false, + message: error.message || "Internal server error", + }); + } +}; + export const checkout = async (req, res) => { try { - const { address, cart, subtotal } = req.body; + const { userr,address, cart, subtotal,orderType } = req.body; +// console.log(req.body); if (cart.length < 1) return res.status(400).json({ message: "cart is empty!" }); if (!address) @@ -55,12 +83,21 @@ export const checkout = async (req, res) => { amount: Number(req.body.subtotal * 100), currency: "INR", }; + // Determine the user ID + let User; + if (userr) { + User = userr; // Use provided user ID + } else { + User = req.user._id; // Use authenticated user ID + } + // console.log(User); const order = await instance.orders.create(options); + // console.log(order); //save order in database if (order?.id) { - const { email } = req.user; - if (!email) - return res.status(400).send({ message: "Please enter the email" }); + // const { email } = req.user; + // if (!email) + // return res.status(400).send({ message: "Please enter the email" }); let addss = await shippingAddress.findById(address); let shipping = { @@ -115,8 +152,9 @@ export const checkout = async (req, res) => { total_amount: subtotal, orderItems, shippingInfo: shipping, - user: req.user._id, + user: User, razorpay_order_id: order?.id, + orderType, }); } else { return res.status(400).json({ @@ -300,6 +338,167 @@ export const paymentVerification = async (req, res) => { }); } }; + +// point of sale payment varification +export const pospaymentVerification = async (req, res) => { + const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = + req.body; + + const body = razorpay_order_id + "|" + razorpay_payment_id; + + const expectedSignature = crypto + .createHmac("sha256", process.env.RAZERPAY_SECRET_KEY) + .update(body.toString()) + .digest("hex"); + + const isAuthentic = expectedSignature === razorpay_signature; + + if (isAuthentic) { + // Database comes here + let findSameOrder = await Order.findOne({ + razorpay_order_id: razorpay_order_id, + }).populate({ + path: "user", + select: "name email -_id", + }); + // console.log("findSameOrder", findSameOrder); + if (findSameOrder) { + (findSameOrder.razorpay_payment_id = razorpay_payment_id), // await Payment.create({ + (findSameOrder.isPaid = true), + (findSameOrder.paidAt = Date.now()), + (findSameOrder.razorpay_signature = razorpay_signature); + // await Payment.create({ + findSameOrder.payment_status = "success"; + + findSameOrder.orderStatus = "new"; + await findSameOrder.save(); + } + //send email to customer + // console.log("findSameOrder", findSameOrder); + await sendEmail({ + to: `${findSameOrder?.user?.email}`, // Change to your recipient + + from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender + + subject: `Your Order #${findSameOrder?.orderID} Confirmation`, + html: `

Welcome to Smellika - Let the Shopping Begin!

+ Hi ${ + findSameOrder?.shippingInfo?.first_Name + }, + +

Great news! Your order #${ + findSameOrder?.orderID + } has been confirmed. Here are the details

+

Shipping Address : ${ + findSameOrder?.shippingInfo?.first_Name + } ${findSameOrder?.shippingInfo?.last_Name} , ${ + findSameOrder?.shippingInfo?.street + } ${findSameOrder?.shippingInfo?.city} ${ + findSameOrder?.shippingInfo?.state + } ${findSameOrder?.shippingInfo?.country}, PIN-${ + findSameOrder?.shippingInfo?.postalCode + }, Phone Number: ${findSameOrder?.shippingInfo?.phone_Number} + ${ + findSameOrder?.shippingInfo?.company_name + ? ",Company Name :" + findSameOrder?.shippingInfo?.company_name + "" + : "" + } ${ + findSameOrder?.shippingInfo?.gst_number + ? ", GST_NO:" + findSameOrder?.shippingInfo?.gst_number + : "" + }

+

Order Items :

+ + + + + + + + + + + + + + + + + + + + ${findSameOrder?.orderItems + ?.map( + (product, index) => ` + + + + + + + + + + + + + + ` + ) + .join("")} + + + + + +
S No.Product NameVariantImageQuantityPriceGST AmountSubTotal
${ + index + 1 + }${ + product.name + }${ + product?.variant_Name + }${
+          product.name
+        }${ + product.quantity + }₹${ + product.price + }₹${ + product?.gst_amount + }₹${ + product?.product_Subtotal + }
Total Amount :₹${ + findSameOrder?.total_amount + }
+ +
+ Best regards,
+ + Team Smellika`, + }); + // console.log("findSameOrder", findSameOrder); + + // // findSameOrder.razorpay_payment_id=razorpay_payment_id,// await Payment.create({ + // findOrder.paidAt = new Date(event.data.object.created * 1000); + // findOrder.isPaid = true; + + // razorpay_signature: { type: String }, + // razorpay_order_id, + // razorpay_payment_id, + // razorpay_signature, + // }); + + res.redirect(`https://admin.smellika.com/#/pos`); + // res.redirect(`http://localhost:3000/#/pos`); + } else { + res.status(400).json({ + success: false, + }); + } +}; + export const handlePayment = async (req, res) => { try { const { email } = req.user; diff --git a/resources/Orders/orderModel.js b/resources/Orders/orderModel.js index 1d7a78c..f40d843 100644 --- a/resources/Orders/orderModel.js +++ b/resources/Orders/orderModel.js @@ -124,7 +124,11 @@ const orderSchema = new mongoose.Schema( enum: ["online", "cod"], default: "online", }, - + orderType: { + type: String, + enum: ["WebSite", "PointOfSale"], + default: "WebSite", + }, payment_status: { type: String, enum: ["pending", "success", "failed"], diff --git a/resources/Orders/orderRoute.js b/resources/Orders/orderRoute.js index 44cfa4b..3ccec85 100644 --- a/resources/Orders/orderRoute.js +++ b/resources/Orders/orderRoute.js @@ -22,12 +22,17 @@ app.use(bodyParser.raw({ type: "application/json" })); import { handlePayment, webhook } from "./StripeCheckOutController.js"; import { checkout, + getRazerpayKey, getRzpkey, paymentVerification, + pospaymentVerification, } from "./RazerPayCheckoutController.js"; +import { poscreateOrderCheckout } from "./PosCheckoutController.js"; const router = express.Router(); //checkout Routes-------------------------// router.route("/checkout/").post(isAuthenticatedUser, createOrderCheckout); +//checkout Routes-------------------------// +router.route("/pos-checkout/").post(isAuthenticatedUser, poscreateOrderCheckout); router.route("/clientid/get/").get(isAuthenticatedUser, getClientId); router.route("/:orderID/capture/payment").post(captureOrderPayment); // --------------------------------------------------- @@ -60,10 +65,11 @@ router .delete(isAuthenticatedUser, authorizeRoles("admin"), deleteOneOrder); //RAZERPAY checkout +router.route("/getRzpKey/:name/:email").get(isAuthenticatedUser, getRazerpayKey); router.route("/getRzpKey/").get(isAuthenticatedUser, getRzpkey); router.route("/Rzpcheckout/").post(isAuthenticatedUser, checkout); router.route("/paymentverification").post(paymentVerification); - +router.route("/pos-paymentverification").post(pospaymentVerification); // router.route("/product/getAll/").get(getAllProduct) export default router; diff --git a/resources/PosOrders/PosCheckoutController.js b/resources/PosOrders/PosCheckoutController.js deleted file mode 100644 index 598c743..0000000 --- a/resources/PosOrders/PosCheckoutController.js +++ /dev/null @@ -1,84 +0,0 @@ -import { POSOrder } from "./PosorderModel.js"; -import { shippingAddress } from "../ShippingAddresses/ShippingAddressModel.js"; - -//generate unique order id -const generateOrderId = async () => { - const currentYear = new Date().getFullYear(); - // Find the latest order to get the last serial number - const latestOrder = await POSOrder.findOne({}, {}, { sort: { orderID: -1 } }); - let serialNumber = 1; - - if (latestOrder) { - const lastYear = parseInt(latestOrder.orderID.substring(0, 4), 10); - if (lastYear === currentYear) { - // If the last order was in the current year, increment the serial number - serialNumber = parseInt(latestOrder.orderID.substring(4), 10) + 1; - } - } - // Pad the serial number with zeros and concatenate with the current year - const paddedSerialNumber = serialNumber.toString().padStart(7, "0"); - const orderId = `${currentYear}${paddedSerialNumber}`; - return orderId; -}; - -export const createOrderCheckout = async (req, res) => { - try { - const { address, cart, user, paymentMode } = - req.body; -// console.log(req.body) - // Perform validation - if (!address || !cart || cart.length === 0 || !user || !paymentMode) { - return res.status(400).json({ message: "Invalid order data" }); - } - - // Retrieve shipping address from database - const shippingInfo = await shippingAddress.findById(address); - if (!shippingInfo) { - return res.status(404).json({ message: "Shipping address not found" }); - } - - // Ensure that addressId is included in the shippingInfo object - const { _id: addressId, ...restOfShippingInfo } = shippingInfo.toObject(); - - // Calculate total amount based on the product_Subtotal of each product - const totalAmount = cart.reduce( - (acc, item) => acc + item.product_Subtotal, - 0 - ); - - // Construct order items array - const orderItems = cart.map((item) => ({ - product: item.product, - name: item.name, - price: item.price, - quantity: item.quantity, - product_Subtotal: item.total_amount, - gst_amount: item.gst_amount, - image: item.image, - variant_Name: item.variant_Name, - })); - - // Generate a unique order ID - const orderId = await generateOrderId(); - - // Create the order document - const order = await POSOrder.create({ - orderID: orderId, - total_amount: totalAmount, - orderItems, - shippingInfo: { - addressId: addressId, // Include the addressId - ...restOfShippingInfo, // Include other shipping information - }, - user, // Assuming you have authenticated users - paymentMode, - }); - - return res.status(201).json({ success: true, order }); - } catch (error) { - console.error("Error creating order:", error); - return res - .status(500) - .json({ success: false, message: "Internal server error" }); - } -}; diff --git a/resources/PosOrders/PosRazerPayCheckoutController.js b/resources/PosOrders/PosRazerPayCheckoutController.js deleted file mode 100644 index f7ae283..0000000 --- a/resources/PosOrders/PosRazerPayCheckoutController.js +++ /dev/null @@ -1,482 +0,0 @@ -import bodyParser from "body-parser"; -import crypto from "crypto"; -import Razorpay from "razorpay"; -import { POSOrder } from "./PosorderModel.js"; -import { shippingAddress } from "../ShippingAddresses/ShippingAddressModel.js"; -import sendEmail from "../../Utils/sendEmail.js"; -const instance = new Razorpay({ - key_id: process.env.RAZERPAY_KEY_ID, - key_secret: process.env.RAZERPAY_SECRET_KEY, -}); - -const generateUniqueOrderId = async () => { - const currentYear = new Date().getFullYear(); - // Find the latest order to get the last serial number - const latestOrder = await POSOrder.findOne({}, {}, { sort: { orderID: -1 } }); - let serialNumber = 1; - - if (latestOrder) { - const lastYear = parseInt(latestOrder.orderID.substring(0, 4), 10); - if (lastYear === currentYear) { - // If the last order was in the current year, increment the serial number - serialNumber = parseInt(latestOrder.orderID.substring(4), 10) + 1; - } - } - // Pad the serial number with zeros and concatenate with the current year - const paddedSerialNumber = serialNumber.toString().padStart(7, "0"); - const orderId = `${currentYear}${paddedSerialNumber}`; - return orderId; -}; - -export const getRzpKey = async (req, res) => { - try { - const { name, email } = req.params; - console.log("name", name, "email", email); - if (!name || !email) { - throw new Error("Name and email are required parameters"); - } - res.status(200).json({ - success: true, - key: process.env.RAZERPAY_KEY_ID, - name, - email, - }); - } catch (error) { - console.error("Error in getRzpKey:", error); - res - .status(500) - .json({ - success: false, - message: error.message || "Internal server error", - }); - } -}; - -export const checkout = async (req, res) => { - try { - console.log(req.body); - const options = { - amount: Number(req.body.subtotal * 100), - currency: "INR", - }; - - console.log("options", options); - - // Wait for the order creation to complete - const order = await instance.orders.create(options); - - console.log("order", order); - - // Check if the order was created successfully - if (!order || !order.id) { - return res.status(400).json({ - success: false, - message: "Failed to create order", - }); - } - - // Extract required data from request parameters and body - // const { email } = req.params; - const { address, cart, user, paymentMode, subtotal } = req.body; - - // Check for required parameters - // if (!email) { - // return res.status(400).send({ message: "Please enter the email" }); - // } - - if (cart.length < 1) { - return res.status(400).json({ message: "Cart is empty!" }); - } - - if (!address) { - return res - .status(404) - .json({ message: "Please select a shipping address!" }); - } - - if (!subtotal) { - return res - .status(404) - .json({ message: "Please provide the product subtotal!" }); - } - - // Fetch shipping information from the database - const shippingInfo = await shippingAddress.findById(address); - if (!shippingInfo) { - return res.status(404).json({ message: "Shipping address not found" }); - } - - console.log("shippinginfo", shippingInfo); - - // Extract addressId and other shipping information - const { _id: addressId, ...restOfShippingInfo } = shippingInfo.toObject(); - - // Prepare order items - const orderItems = cart.map((item) => ({ - product: item.product, - name: item.name, - price: item.price, - quantity: item.quantity, - product_Subtotal: item.total_amount, - gst_amount: item.gst_amount, - image: item.image, - variant_Name: item.variant_Name, - })); - - // Generate a unique order ID - const orderId = await generateUniqueOrderId(); - - // Create the order in the database - const orders = await POSOrder.create({ - orderID: orderId, - total_amount: subtotal, - orderItems, - shippingInfo: { - addressId: addressId, - ...restOfShippingInfo, - }, - user, - paymentMode, - razorpay_order_id: order.id, - }); - - res.status(200).json({ - success: true, - order, - }); - } catch (error) { - console.error("Error in checkout:", error); - res - .status(500) - .json({ - success: false, - message: error.message || "Internal server error", - }); - } -}; - -export const paymentVerification = async (req, res) => { - const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = - req.body; - console.log(req.body); - const body = razorpay_order_id + "|" + razorpay_payment_id; - - const expectedSignature = crypto - .createHmac("sha256", process.env.RAZERPAY_SECRET_KEY) - .update(body.toString()) - .digest("hex"); - - const isAuthentic = expectedSignature === razorpay_signature; - - if (isAuthentic) { - // Database comes here - let findSameOrder = await POSOrder.findOne({ - razorpay_order_id: razorpay_order_id, - }).populate({ - path: "user", - select: "name email -_id", - }); - // console.log("findSameOrder", findSameOrder); - if (findSameOrder) { - (findSameOrder.razorpay_payment_id = razorpay_payment_id), // await Payment.create({ - (findSameOrder.isPaid = true), - (findSameOrder.paidAt = Date.now()), - (findSameOrder.razorpay_signature = razorpay_signature); - // await Payment.create({ - findSameOrder.payment_status = "success"; - - findSameOrder.orderStatus = "new"; - await findSameOrder.save(); - } - //send email to customer - // console.log("findSameOrder", findSameOrder); - await sendEmail({ - to: `${findSameOrder?.user?.email}`, // Change to your recipient - - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - - subject: `Your POSOrder #${findSameOrder?.orderID} Confirmation`, - html: `

Welcome to Smellika - Let the Shopping Begin!

- Hi ${ - findSameOrder?.shippingInfo?.first_Name - }, - -

Great news! Your order #${ - findSameOrder?.orderID - } has been confirmed. Here are the details

-

Shipping Address : ${ - findSameOrder?.shippingInfo?.first_Name - } ${findSameOrder?.shippingInfo?.last_Name} , ${ - findSameOrder?.shippingInfo?.street - } ${findSameOrder?.shippingInfo?.city} ${ - findSameOrder?.shippingInfo?.state - } ${findSameOrder?.shippingInfo?.country}, PIN-${ - findSameOrder?.shippingInfo?.postalCode - }, Phone Number: ${findSameOrder?.shippingInfo?.phone_Number}

-

POSOrder Items :

- - - - - - - - - - - - - - - - - - ${findSameOrder?.orderItems - ?.map( - (product, index) => ` - - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${
-          product.name
-        }${ - product.quantity - }₹${ - product.price - }₹${ - product?.gst_amount - }₹${ - product.product_Subtotal - }
Total Amount :₹${ - findSameOrder?.total_amount - }
- -
- Best regards,
- - Team Smellika`, - }); - // console.log("findSameOrder", findSameOrder); - - // // findSameOrder.razorpay_payment_id=razorpay_payment_id,// await Payment.create({ - // findOrder.paidAt = new Date(event.data.object.created * 1000); - // findOrder.isPaid = true; - - // razorpay_signature: { type: String }, - // razorpay_order_id, - // razorpay_payment_id, - // razorpay_signature, - // }); - - // res.redirect(`https://admin.smellika.com/#/pos`); - res.redirect(`http://localhost:3000/#/pos`); - } else { - res.status(400).json({ - success: false, - }); - } -}; -export const handlePayment = async (req, res) => { - try { - const { email } = req.user; - if (!email) - return res.status(400).send({ message: "Please enter the email" }); - const { address, cart, subtotal } = req.body; - if (cart.length < 1) - return res.status(400).json({ message: "cart is empty!" }); - switch (true) { - //validation - case !address: { - return res.status(404).json({ msg: "please provide shipping address" }); - } - case !subtotal: { - return res.status(404).json({ msg: "please provide product subtotal" }); - } - } - let addss = await shippingAddress.findById(address); - // console.log(addss?.postalCode); - let shipping = { - first_Name: addss.first_Name, - last_Name: addss.last_Name, - phone_Number: addss.phone_Number, - street: addss.street, - city: addss.city, - state: addss.state, - postalCode: addss?.postalCode, - country: addss.country, - addressId: address, - }; - const orderItems = await cart.map((item) => ({ - product: item.product._id, - name: item.product.name, - price: item.product.total_amount, - image: item.product.image, - quantity: item.quantity, - product_Subtotal: item.subtotal, - })); - - // console.log("line", lineItems[0]); - const Id = await generateUniqueOrderId(); - const order = await POSOrder.create({ - orderID: Id, - total_amount: subtotal, - orderItems, - shippingInfo: shipping, - user: req.user._id, - }); - console.log("fffffffff", order, "llllllllll"); - const lineItems = await cart.map((item) => ({ - price_data: { - currency: "inr", - product_data: { - name: item.product.name, - - images: [item.product.image[0]?.url], - }, - unit_amount: Number(item.product.total_amount) * 100, - }, - quantity: Number(item.quantity), - })); - if (order) { - const session = await stripe.checkout.sessions.create({ - payment_method_types: ["card"], - line_items: lineItems, - mode: "payment", - customer_email: `${email}`, - metadata: { - orderId: order._id.toString(), - - // Add any other key-value pairs as needed - }, - // success_url: `${process.env.FRONTEND_URL}/cart`, - sccess_url: `httphttp://localhost:5000/#/success`, - // cancel_url: `${process.env.FRONTEND_URL}/error`, - cancel_url: `http://localhost:5000/#/error`, - }); - // res.json({ sessionId: session.id }); - - res.status(200).send({ message: "order created", url: session.url }); - } - } catch (err) { - console.log(err); - res.status(500).send({ message: "Something went wrong", err }); - } -}; - -export const webhook = async (req, res) => { - const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; - const signature = req.headers["stripe-signature"]; - let event; - if (webhookSecret) { - try { - event = stripe.webhooks.constructEvent( - req.body, - signature, - webhookSecret - ); - } catch (err) { - console.log(`❌ Error message: ${err.message}`); - res.status(400).send(`Webhook Error: ${err.message}`); - return; - } - } - - if (event.type === "checkout.session.completed") { - // console.log("dddddddddddd", event.data); - const findOrder = await POSOrder.findById( - event.data.object.metadata?.orderId - ); - findOrder.paypal_payer_id = event.data.object.id; - findOrder.paidAt = new Date(event.data.object.created * 1000); - findOrder.isPaid = true; - if (event.data.object?.payment_status === "paid") { - findOrder.payment_status = "success"; - } else { - findOrder.payment_status = "failed"; - } - findOrder.orderStatus = "new"; - await findOrder.save(); - await sendEmail({ - to: `${event.data.object.customer_email}`, // Change to your recipient - - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - - subject: `Your POSOrder #${findOrder?.orderID} Confirmation`, - html: `

Welcome to Smellika - Let the Shopping Begin!

- Hi ${findOrder?.shippingInfo?.first_Name}, - -

Great news! Your order #${findOrder?.orderID} has been confirmed. Here are the details

-
- Best regards,
- - Team Smellika`, - }); - - // Items: [List of Purchased Items] - // Total Amount: [Total Amount] - // Shipping Address: [Shipping Address] - - // We'll keep you updated on the shipping progress. Thanks for choosing Smellika! - - // Best regards - // Team Smellika - console.log( - "event.data.object", - event.data.object, - "---------------------" - ); - - console.log(`💰 Payment status: ${event.data.object?.payment_status}`); - - // Saving the payment details in the database - // const payment = await Payment.create({ - // customer_email: event.data.object.customer_email, - // amount: event.data.object.amount_total / 100, - // paymentId: event.data.object.id, - // paymentStatus: event.data.object.payment_status, - // createdAt: event.data.object.created, - // }); - } - // if (event.type === "checkout.session.completed") { - // console.log("dddddddddddd", event.data); - // console.log("event.data.object", event.data.object); - // console.log(`💰 Payment status: ${event.data.object?.payment_status}`); - // payment_intent.payment_failed; - - // // Saving the payment details in the database - // // const payment = await Payment.create({ - // // customer_email: event.data.object.customer_email, - // // amount: event.data.object.amount_total / 100, - // // paymentId: event.data.object.id, - // // paymentStatus: event.data.object.payment_status, - // // createdAt: event.data.object.created, - // // }); - // } - - // Return a 200 res to acknowledge receipt of the event - res.status(200).end(); - // res.send().end(); -}; diff --git a/resources/PosOrders/PosorderController.js b/resources/PosOrders/PosorderController.js deleted file mode 100644 index 6a02741..0000000 --- a/resources/PosOrders/PosorderController.js +++ /dev/null @@ -1,552 +0,0 @@ -import sendEmail from "../../Utils/sendEmail.js"; -import { POSOrder } from "./PosorderModel.js"; - -export const getAllOrder = async (req, res) => { - try { - const { status } = req.params; - const order = await POSOrder.find({ - IsStoreDelivery: "Cash", - orderStatus: status, - }) - .populate({ - path: "user", - select: "name -_id", - }) - .populate({ - path: "shippingInfo.addressId", - }) - .sort({ updatedAt: -1 }); - if (order) { - res.status(201).json({ - success: true, - order, - message: "All POSOrder Fetched", - }); - } - } catch (error) { - res.status(500).json({ - success: false, - message: error.message ? error.message : "Something went Wrong", - }); - } -}; -export const getOrders = async (req, res) => { - try { - const order = await POSOrder.find({ - // payment_status: "success", - }) - .populate({ - path: "user", - select: "name -_id", - }) - .populate({ - path: "shippingInfo.addressId", - }) - .sort({ updatedAt: -1 }); - if (order) { - res.status(201).json({ - success: true, - order, - message: "All POSOrder Fetched", - }); - } - } catch (error) { - res.status(500).json({ - success: false, - message: error.message ? error.message : "Something went Wrong", - }); - } -}; -export const getSingleOrder = async (req, res) => { - try { - if (!req.params.id) - return res.status(400).json({ message: "please Provide POSOrder Id" }); - - const order = await POSOrder.findById(req.params.id) - .populate({ - path: "user", - select: "name email -_id", - }) - .populate({ - path: "shippingInfo.addressId", - }) - .sort({ createdAt: -1 }); - if (order) { - res.status(201).json({ - success: true, - order, - message: " POSOrder Fetched", - }); - } - } catch (error) { - res.status(500).json({ - success: false, - message: error.message ? error.message : "Something went Wrong", - }); - } -}; - -//get self User POSOrder -export const getUserSelf = async (req, res) => { - if (!req?.user) return res.status(400).json({ message: "please login !" }); - try { - const order = await POSOrder.find({ - user: req.user?._id, - payment_status: "success", - }).sort({ createdAt: -1 }); - - if (order) { - return res.status(200).json({ - success: true, - order, - message: "self POSOrder fetched", - }); - } - } catch (error) { - res.status(500).json({ - success: false, - message: error.message ? error.message : "Something went Wrong", - }); - } -}; - -export const deleteOneOrder = async (req, res) => { - try { - if (!req?.user) return res.status(400).json({ message: "please login !" }); - if (!req.params.id) - return res.status(400).json({ message: "please Provide POSOrder Id" }); - const getOrder = await POSOrder.findById(req.params.id); - if (!getOrder) { - return res.status(404).json({ - success: false, - message: "No POSOrder Found!", - }); - } - const order = await POSOrder.findByIdAndDelete(req.params.id); - - await order.remove(); - res.status(200).json({ - success: true, - message: "POSOrder Deleted Successfully!!", - }); - } catch (error) { - res.status(500).json({ - success: false, - message: error.message ? error.message : "Something went Wrong", - }); - } -}; -export const updateOrderStatusById = async (req, res) => { - try { - let body = { orderStatus: req.body.status }; - - const currentDate = new Date(); - body["status_timeline." + req.body.status] = currentDate; - // if (req.body?.package_weight) body.package_weight = req.body.package_weight; - const order = await POSOrder.findById(req.params.id).populate({ - path: "user", - select: "name email -_id", - }); - // console.log("order", order); - // const parentData = { email: order?.parent?.email }; - if (req.body.status === "cancelled") { - body["order_Cancelled_Reason"] = req.body?.ReasonforCancellation; - body["iscancelled"] = true; - await POSOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.user?.email}`, // Change to your recipient - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `POSOrder #${order?.orderID} Update: Cancellation and Refund Process`, - html: ` Hi ${ - order?.shippingInfo?.first_Name - }, -

We hope this message finds you well. We're writing to inform you that your order ${ - order?.orderID - } has been canceled. We understand that circumstances may change, and we're here to assist you throughout the process.

- - -

Items :

- - - - - - - - - - - - - - - - - - ${order?.orderItems - ?.map( - (product, index) => ` - - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${
-          product.name
-        }${ - product.quantity - }₹${ - product.price - }₹${ - product?.gst_amount - }₹${ - product.product_Subtotal - }
Total Amount :₹${ - order?.total_amount - }
-

Cancellation Reason : ${ - req.body?.ReasonforCancellation - }

-

Refund Information: The amount from your canceled order will be processed for a refund. Please allow up to 7 working days for the amount to be transferred back to your original payment method.

- -
If you have any concerns or further questions, please feel free to reply to this email. We appreciate your understanding and hope to serve you better in the future. -
-
- Best regards,
- - Team Smellika`, - }); - return res - .status(200) - .json({ status: "ok", message: "POSOrder status updated successfully!" }); - } else if (req.body.status === "processing") { - await POSOrder.findByIdAndUpdate(order._id, body); - - await sendEmail({ - to: `${order?.user?.email}`, // Change to your recipient - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `Your POSOrder #${order?.orderID} is in Processing!`, - html: `

Exciting news! Your order #${ - order?.orderID - } has entered the processing phase. Our team is diligently preparing your items for dispatch. Rest assured, we're working hard to ensure everything is perfect for you.

- Hi ${ - order?.shippingInfo?.first_Name - }, -

POSOrder Status : Processing

-

POSOrder Items :

- - - - - - - - - - - - - - - - - - ${order?.orderItems - ?.map( - (product, index) => ` - - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${
-          product.name
-        }${ - product.quantity - }₹${ - product.price - }₹${ - product?.gst_amount - }₹${ - product.product_Subtotal - }
Total Amount :₹${ - order?.total_amount - }
-
We'll send you another email with the tracking details as soon as your order is dispatched. If you have any questions or need assistance, feel free to reply to this email.
-
Thank you for choosing Smellika!
-
- Best regards,
- - Team Smellika`, - }); - return res - .status(200) - .json({ status: "ok", message: "POSOrder status updated successfully!" }); - } - // else if (body.status === "dispatched") { - // const noBalanceRemaining = - // order?.sales_items?.filter((e) => Number(e?.balance_quantity) > 0) - // ?.length === 0 - // ? true - // : false; - // if (!noBalanceRemaining) - // return res - // .status(400) - // .json({ message: "Few items still have balance quantity!" }); - // await OrderDispatchedEmail(parentData.email, order.order_id, body); - // await Invoice.updateMany( - // { order: order._id, status: { $in: ["processing"] } }, - // { status: body.status, "status_timeline.dispatched": currentDate } - // ); - // } else if (body.status === "delivered") { - // await OrderDeliveredEmail(parentData.email, order.order_id); - // await Invoice.updateMany( - // { order: order._id, status: { $in: ["processing", "dispatched"] } }, - // { status: body.status, "status_timeline.delivered": currentDate } - // ); - // } - else if (req.body.status === "dispatched") { - body["courier_name"] = req.body.courierName; - body["courier_tracking_id"] = req.body.TrackingID; - await POSOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.user?.email}`, // Change to your recipient - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `Your POSOrder #${order?.orderID} is On Its Way!`, - html: ` Hi ${ - order?.shippingInfo?.first_Name - }, -

Exciting news! Your order #${ - order?.orderID - } has been dispatched and is en route to you. 🚚 Here are the details:

- -

Courier Name : ${ - req.body.courierName - }

-

Courier Tracking ID : ${ - req.body.TrackingID - }

- - -

Items :

- - - - - - - - - - - - - - - - - - ${order?.orderItems - ?.map( - (product, index) => ` - - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${
-          product.name
-        }${ - product.quantity - }₹${ - product.price - }₹${ - product?.gst_amount - }₹${ - product.product_Subtotal - }
Total Amount :₹${ - order?.total_amount - }
-

POSOrder Status : Dispatched

-

If you have any questions or need assistance, feel free to reply to this email. -

-
Thanks for choosing Smellika! We hope you enjoy your purchase. -
-
- Best regards,
- - Team Smellika`, - }); - return res - .status(200) - .json({ status: "ok", message: "POSOrder status updated successfully!" }); - } else if (req.body.status === "delivered") { - body["isDelivered"] = true; - body["DeliveredDate"] = req.body.DDate; - await POSOrder.findByIdAndUpdate(order._id, body); - await sendEmail({ - to: `${order?.user?.email}`, // Change to your recipient - from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender - subject: `Your POSOrder #${order?.orderID} Has Been Delivered!`, - html: ` Hi ${ - order?.shippingInfo?.first_Name - }, -

Great news! Your order #${ - order?.orderID - } has been successfully delivered to your doorstep. We hope everything is just as you expected!

-

Items :

- - - - - - - - - - - - - - - - - - ${order?.orderItems - ?.map( - (product, index) => ` - - - - - - - - - - - - - ` - ) - .join("")} - - - - - -
S No.Product NameImageQuantityPriceGST AmountSubTotal
${ - index + 1 - }${ - product.name - }${
-                product.name
-              }${ - product.quantity - }₹${ - product.price - }₹${ - product?.gst_amount - }₹${ - product.product_Subtotal - }
Total Amount :₹${ - order?.total_amount - }
-

Delivery Date: ${ - req.body.DDate - }

-

Your satisfaction is our priority, and we'd love to hear about your experience. Please take a moment to share your thoughts by leaving a review. Your feedback is invaluable to us! -

-
If you have any questions or concerns about your order, feel free to reply to this email. -
-
Thank you for choosing Smellika! We hope to serve you again soon. - -
-
- Best regards,
- - Team Smellika`, - }); - - return res - .status(200) - .json({ status: "ok", message: "POSOrder status updated successfully!" }); - } else { - // await POSOrder.findByIdAndUpdate(order._id, body); - // console.log(order); - res - .status(200) - .json({ status: "ok", message: "POSOrder status updated successfully!" }); - } - } catch (error) { - console.log(error); - res - .status(500) - .json({ message: error?.message || "Something went wrong!" }); - } -}; diff --git a/resources/PosOrders/PosorderModel.js b/resources/PosOrders/PosorderModel.js deleted file mode 100644 index 2f3032d..0000000 --- a/resources/PosOrders/PosorderModel.js +++ /dev/null @@ -1,161 +0,0 @@ -import mongoose from "mongoose"; - -const POSorderSchema = new mongoose.Schema( - { - orderID: { - type: String, - required: true, - unique: true, - }, - user: { - type: mongoose.Schema.ObjectId, - ref: "User", - required: true, - }, - shippingInfo: { - first_Name: { - type: String, - required: true, - }, - last_Name: { - type: String, - required: true, - }, - phone_Number: { - type: Number, - required: true, - }, - street: { - type: String, - required: true, - }, - city: { - type: String, - required: true, - trim: true, - }, - state: { - type: String, - required: true, - }, - postalCode: { - type: String, - required: true, - trim: true, - // Add a regular expression to enforce a specific postal code format - // For example, assuming a 5-digit format for the United States - match: /^\d{6}$/, - }, - country: { - type: String, - required: true, - }, - addressId: { - type: mongoose.Schema.ObjectId, - ref: "ShippingAddress", - required: true, - }, - }, - orderItems: [ - { - name: { - type: String, - default: "", - }, - price: { - type: Number, - default: "", - }, - variant_Name: { type: String, default: "" }, - quantity: { - type: Number, - default: "", - default: 1, - }, - image: [{}], - - product_Subtotal: { - type: Number, - default: "", - }, - gst_amount: { - type: Number, - default: "", - }, - gst_rate: { - type: Number, - default: "", - }, - tax_Name: { - type: String, - default: "", - }, - product: { - type: mongoose.Schema.ObjectId, - ref: "Product", - }, - }, - ], - - shipping_charge: { type: Number, default: 0 }, - tax_amount: { type: Number, default: 0 }, - total_amount: { type: Number, default: 0 }, - weight: { type: Number, default: 0 }, - - paymentMode: { - type: String, - enum: ["QRCode", "Cash"], - }, - payment_status: { - type: String, - enum: ["pending", "success", "failed"], - }, - isPaid: { - type: Boolean, - default: false, - }, - paidAt: { - type: Date, - }, - - orderStatus: { - type: String, - enum: [ - "new", - "processing", - "dispatched", - "delivered", - "cancelled", - "returned", - ], - default: "new", - }, - razorpay_payment_id: { type: String }, - razorpay_order_id: { type: String }, - razorpay_signature: { type: String }, - isDelivered: { type: Boolean, required: true, default: false }, - DeliveredDate: { type: String, default: "" }, - - // deliveredAt: { type: Date }, - status_timeline: { - new: { type: Date }, - processing: { type: Date }, - dispatched: { type: Date }, - delivered: { type: Date }, - cancelled: { type: Date }, - returned: { type: Date }, - }, - iscancelled: { - type: Boolean, - default: false, - }, - order_Cancelled_Reason: { - type: String, - }, - courier_name: { type: String }, - courier_tracking_id: { type: String }, - }, - { timestamps: true } -); - -export const POSOrder = mongoose.model("POSOrder", POSorderSchema); diff --git a/resources/PosOrders/PosorderRoute.js b/resources/PosOrders/PosorderRoute.js deleted file mode 100644 index 65dace4..0000000 --- a/resources/PosOrders/PosorderRoute.js +++ /dev/null @@ -1,51 +0,0 @@ -import bodyParser from "body-parser"; -import { - deleteOneOrder, - getAllOrder, - getOrders, - getSingleOrder, - getUserSelf, - updateOrderStatusById, -} from "./PosorderController.js"; -import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; -import express from "express"; -import { - createOrderCheckout, -} from "./PosCheckoutController.js"; -import { checkout, getRzpKey, paymentVerification } from "./PosRazerPayCheckoutController.js"; - -const app = express(); - -// Configure bodyParser to parse the raw request body as a buffer -app.use(bodyParser.raw({ type: "application/json" })); - - -const router = express.Router(); -//checkout Routes-------------------------// -router.route("/pos-checkout/").post(isAuthenticatedUser, createOrderCheckout); -// --------------------------------------------------- - -// -------------------------------------------------- -//get user self -router.route("/user/self").get(isAuthenticatedUser, getUserSelf); - -//admin route -router - .route("/pos-getAll/:status") - .get(isAuthenticatedUser, authorizeRoles("admin"), getAllOrder); -router - .route("/pos-getAll/") - .get(isAuthenticatedUser, authorizeRoles("admin"), getOrders); -router.route("/pos-getOne/:id").get(isAuthenticatedUser, getSingleOrder); -router - .route("/pos-change/status/:id") - .patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById); - -router - .route("/pos-delete/:id") - .delete(isAuthenticatedUser, authorizeRoles("admin"), deleteOneOrder); -//RAZERPAY checkout -router.route("/getRzpKey/:name/:email").get(isAuthenticatedUser, getRzpKey); -router.route("/Rzpcheckout/").post(isAuthenticatedUser, checkout); -router.route("/paymentverification").post(paymentVerification); -export default router;