ctrlv-ince/gamezone-react-native
0
1const { Order } = require('../models/order');2const { Product } = require('../models/product');3const { Expo } = require('expo-server-sdk');4 5// Create a new Expo SDK client6let expo = new Expo();7 8exports.getOrders = async (req, res) => {9 const orderList = await Order.find()10 .populate('user', 'name photo')11 .populate('orderItems.product')12 .sort({ dateOrdered: -1 });13 14 if (!orderList) {15 return res.status(500).json({ success: false });16 }17 res.send(orderList);18};19 20exports.getOrdersByUser = async (req, res) => {21 const userOrderList = await Order.find({ user: req.params.userId })22 .populate({23 path: 'orderItems.product',24 select: 'name images price',25 })26 .sort({ dateOrdered: -1 });27 28 if (!userOrderList) {29 return res.status(500).json({ success: false });30 }31 res.send(userOrderList);32};33 34exports.getOrderById = async (req, res) => {35 const order = await Order.findById(req.params.id)36 .populate('user', 'name email pushToken')37 .populate({38 path: 'orderItems.product',39 populate: 'category'40 });41 42 if (!order) {43 return res.status(500).json({ success: false });44 }45 res.send(order);46};47 48exports.createOrder = async (req, res) => {49 // Build order items with price looked up from the Product model50 const orderItems = await Promise.all(51 req.body.orderItems.map(async (item) => {52 const product = await Product.findById(item.product).select('price');53 if (!product) throw new Error(`Product not found: ${item.product}`);54 return {55 quantity: item.quantity,56 product: item.product,57 price: product.price,58 };59 })60 );61 62 let order = new Order({63 orderItems: orderItems,64 status: req.body.status || 'Pending',65 user: req.body.user,66 });67 order = await order.save();68 69 if (!order) return res.status(400).send('the order cannot be created!');70 71 res.send(order);72};73 74exports.updateOrder = async (req, res) => {75 // First find previous order to check status change76 const previousOrder = await Order.findById(req.params.id);77 if (!previousOrder) return res.status(400).send('Invalid Order ID');78 79 const order = await Order.findByIdAndUpdate(80 req.params.id,81 {82 status: req.body.status83 },84 { new: true }85 ).populate('user');86 87 if (!order) return res.status(400).send('the order cannot be update!');88 89 // Decrement stock if transitioning to Delivered90 if (req.body.status === 'Delivered' && previousOrder.status !== 'Delivered') {91 const bulkUpdateOps = order.orderItems.map(item => {92 return {93 updateOne: {94 filter: { _id: item.product },95 update: { $inc: { stock: -item.quantity } }96 }97 };98 });99 if (bulkUpdateOps.length > 0) {100 await Product.bulkWrite(bulkUpdateOps);101 console.log('Stock decremented for delivered order');102 }103 }104 105 // 101: Notify user of status update106 if (order.user && order.user.pushToken) {107 if (!Expo.isExpoPushToken(order.user.pushToken)) {108 console.error(`Push token ${order.user.pushToken} is not a valid Expo push token`);109 } else {110 console.log(`Sending notification to user: ${order.user._id} via token: ${order.user.pushToken}`);111 const messages = [{112 to: order.user.pushToken,113 sound: 'default',114 title: 'Order Status Updated',115 body: `Your order status has been updated to ${order.status}`,116 data: { orderId: order._id }117 }];118 119 try {120 const chunks = expo.chunkPushNotifications(messages);121 for (const chunk of chunks) {122 const ticketChunk = await expo.sendPushNotificationsAsync(chunk);123 console.log("Push notification response:", JSON.stringify(ticketChunk));124 }125 } catch (error) {126 console.error("Error sending push notification", error);127 }128 }129 } else {130 console.log("Skipping notification: User or pushToken missing", {131 userId: order.user ? order.user._id : 'missing',132 hasPushToken: !!(order.user && order.user.pushToken)133 });134 }135 136 res.send(order);137};138 139exports.deleteOrder = async (req, res) => {140 try {141 const order = await Order.findByIdAndDelete(req.params.id);142 if (order) {143 return res.status(200).json({ success: true, message: 'the order is deleted!' });144 } else {145 return res.status(404).json({ success: false, message: 'order not found!' });146 }147 } catch (err) {148 return res.status(500).json({ success: false, error: err });149 }150};151 