Spaces:
Running
Running
feat: implement business date utility and financial reporting system including expense tracking, platform sales, and profit-loss analysis endpoints
ec62259 Download src/controllers/orderController.js from aliroohan179/face: direct link, hf CLI and curl.
- Browser
- Download file 5.63 kB
-
https://huggingface.co/spaces/aliroohan179/face/resolve/main/src/controllers/orderController.js
- Command line
-
hf download hf://spaces/aliroohan179/face/src/controllers/orderController.js
-
curl -L -o orderController.js https://huggingface.co/spaces/aliroohan179/face/resolve/main/src/controllers/orderController.js
5.63 kB
| const Order = require('../models/Order'); | |
| const { log } = require('../utils/activityLogger'); | |
| const { | |
| getBusinessDate, | |
| getBusinessDayRange, | |
| getBusinessDateRange, | |
| getCurrentBusinessDayRange, | |
| } = require('../utils/businessDate'); | |
| // POST /api/orders β create single order | |
| exports.createOrder = async (req, res) => { | |
| const body = req.body; | |
| // localId acts as idempotency key β if already synced, return existing | |
| const existing = await Order.findOne({ localId: body.localId }); | |
| if (existing) return res.status(200).json(existing); | |
| const order = await Order.create({ ...body, cashier: req.user._id }); | |
| log(req.user, 'CREATE_ORDER', { entity: 'Order', entityId: order._id, detail: `Rs.${order.netTotal} ${order.orderType}` }); | |
| res.status(201).json(order); | |
| }; | |
| // POST /api/orders/bulk-sync β push batch of offline orders | |
| exports.bulkSync = async (req, res) => { | |
| const { orders } = req.body; | |
| if (!Array.isArray(orders) || orders.length === 0) return res.status(400).json({ message: 'Orders array required' }); | |
| const results = []; | |
| for (const orderData of orders) { | |
| const existing = await Order.findOne({ localId: orderData.localId }); | |
| if (existing) { | |
| if (orderData.status === 'voided' && existing.status !== 'voided') { | |
| existing.status = 'voided'; | |
| existing.voidedBy = req.user._id; | |
| existing.voidedAt = new Date(); | |
| await existing.save(); | |
| results.push({ localId: orderData.localId, status: 'updated_to_voided', id: existing._id }); | |
| } else { | |
| results.push({ localId: orderData.localId, status: 'already_synced', id: existing._id }); | |
| } | |
| } else { | |
| const order = await Order.create({ ...orderData, cashier: req.user._id }); | |
| results.push({ localId: orderData.localId, status: 'synced', id: order._id }); | |
| } | |
| } | |
| log(req.user, 'BULK_SYNC', { detail: `${results.length} orders synced` }); | |
| res.json({ results }); | |
| }; | |
| // GET /api/orders β owner sees all with filters; cashier sees active shift's orders only | |
| exports.getOrders = async (req, res) => { | |
| const isOwner = req.user.role === 'owner'; | |
| const { from, to, status, orderType, page = 1, limit = 100 } = req.query; | |
| const filter = {}; | |
| if (isOwner) { | |
| // Owner: apply all filters as requested | |
| if (status) filter.status = status; | |
| if (orderType) filter.orderType = orderType; | |
| if (from || to) { | |
| if (from && to && from === to) { | |
| const { from: start, to: end } = getBusinessDayRange(from); | |
| filter.createdAt = { $gte: start, $lte: end }; | |
| } else { | |
| const { from: start, to: end } = getBusinessDateRange(from, to); | |
| filter.createdAt = { $gte: start, $lte: end }; | |
| } | |
| } | |
| } else { | |
| // Cashier: active business shift orders by default, or specific date range if passed | |
| if (from || to) { | |
| if (from && to && from === to) { | |
| const { from: start, to: end } = getBusinessDayRange(from); | |
| filter.createdAt = { $gte: start, $lte: end }; | |
| } else { | |
| const { from: start, to: end } = getBusinessDateRange(from, to); | |
| filter.createdAt = { $gte: start, $lte: end }; | |
| } | |
| } else { | |
| const { from: start, to: end } = getCurrentBusinessDayRange(); | |
| filter.createdAt = { $gte: start, $lte: end }; | |
| } | |
| if (status) filter.status = status; | |
| } | |
| const [orders, total] = await Promise.all([ | |
| Order.find(filter) | |
| .populate('cashier', 'name username') | |
| .sort({ createdAt: -1 }) | |
| .skip((page - 1) * limit) | |
| .limit(Number(limit)), | |
| Order.countDocuments(filter), | |
| ]); | |
| res.json({ orders, total, page: Number(page), pages: Math.ceil(total / limit) }); | |
| }; | |
| // PUT /api/orders/:id/void β requires admin PIN | |
| exports.voidOrder = async (req, res) => { | |
| const { pin } = req.body; | |
| if (!pin) return res.status(400).json({ message: 'Admin PIN required' }); | |
| // Only owner can void post-payment | |
| if (req.user.role !== 'owner') return res.status(403).json({ message: 'Only owner can void orders' }); | |
| const User = require('../models/User'); | |
| const owner = await User.findById(req.user._id); | |
| const pinOk = await owner.matchPin(pin); | |
| if (!pinOk) return res.status(401).json({ message: 'Incorrect PIN' }); | |
| const order = await Order.findById(req.params.id); | |
| if (!order) return res.status(404).json({ message: 'Order not found' }); | |
| if (order.status === 'voided') return res.status(400).json({ message: 'Order already voided' }); | |
| order.status = 'voided'; | |
| order.voidedBy = req.user._id; | |
| order.voidedAt = new Date(); | |
| await order.save(); | |
| log(req.user, 'VOID_ORDER', { entity: 'Order', entityId: order._id, detail: `Voided order Rs.${order.netTotal}` }); | |
| res.json(order); | |
| }; | |
| // PUT /api/orders/:id/cancel β cashier cancel (current shift's orders only, no PIN required) | |
| exports.cancelOrder = async (req, res) => { | |
| const order = await Order.findById(req.params.id); | |
| if (!order) return res.status(404).json({ message: 'Order not found' }); | |
| if (order.status === 'voided') return res.status(400).json({ message: 'Order already cancelled' }); | |
| // Cashiers can only cancel orders from the active business shift | |
| const { from: currentShiftStart } = getCurrentBusinessDayRange(); | |
| if (order.createdAt < currentShiftStart) { | |
| return res.status(403).json({ message: 'Cannot cancel orders from previous shifts. Ask the owner to void it.' }); | |
| } | |
| order.status = 'voided'; | |
| order.voidedBy = req.user._id; | |
| order.voidedAt = new Date(); | |
| await order.save(); | |
| log(req.user, 'CASHIER_CANCEL', { entity: 'Order', entityId: order._id, detail: `Cashier cancelled Rs.${order.netTotal}` }); | |
| res.json(order); | |
| }; | |