diff --git a/backend/src/main/java/com/rit/canteen/sales/controller/OrderController.java b/backend/src/main/java/com/rit/canteen/sales/controller/OrderController.java index 89f0771d..44f92d63 100644 --- a/backend/src/main/java/com/rit/canteen/sales/controller/OrderController.java +++ b/backend/src/main/java/com/rit/canteen/sales/controller/OrderController.java @@ -120,6 +120,24 @@ public class OrderController { } } + if (isStaff()) { + Optional posUserOpt = userRepository.findByMobileNumber("0000000000"); + User posUser; + if (posUserOpt.isPresent()) { + posUser = posUserOpt.get(); + } else { + posUser = new User(); + posUser.setMobileNumber("0000000000"); + posUser.setName("POS"); + posUser.setPinHash("NOT_APPLICABLE"); + posUser.setCreatedAt(LocalDateTime.now()); + posUser.setUpdatedAt(LocalDateTime.now()); + posUser = userRepository.save(posUser); + } + order.setUserId(posUser.getId()); + order.setOrderType("POS"); + } + if (order.getItems() == null || order.getItems().isEmpty()) { return ResponseEntity.badRequest().body(Map.of("success", false, "message", "Order must have items")); } diff --git a/backend/src/main/java/com/rit/canteen/sales/model/DashboardStats.java b/backend/src/main/java/com/rit/canteen/sales/model/DashboardStats.java index 0c18e795..7c4f5453 100644 --- a/backend/src/main/java/com/rit/canteen/sales/model/DashboardStats.java +++ b/backend/src/main/java/com/rit/canteen/sales/model/DashboardStats.java @@ -9,6 +9,8 @@ public class DashboardStats { private long totalExpenses; private long periodExpenses; private long suspendedUserCount; + private long periodStoreRevenue; + private long totalStoreRevenue; public DashboardStats() {} @@ -23,6 +25,19 @@ public class DashboardStats { this.suspendedUserCount = suspendedUserCount; } + public DashboardStats(long totalSales, long periodRevenue, int activeOrders, int dailyCustomers, double growth, long totalExpenses, long periodExpenses, long suspendedUserCount, long periodStoreRevenue, long totalStoreRevenue) { + this.totalSales = totalSales; + this.periodRevenue = periodRevenue; + this.activeOrders = activeOrders; + this.dailyCustomers = dailyCustomers; + this.growth = growth; + this.totalExpenses = totalExpenses; + this.periodExpenses = periodExpenses; + this.suspendedUserCount = suspendedUserCount; + this.periodStoreRevenue = periodStoreRevenue; + this.totalStoreRevenue = totalStoreRevenue; + } + public long getTotalSales() { return totalSales; } public void setTotalSales(long totalSales) { this.totalSales = totalSales; } @@ -46,4 +61,10 @@ public class DashboardStats { public long getSuspendedUserCount() { return suspendedUserCount; } public void setSuspendedUserCount(long suspendedUserCount) { this.suspendedUserCount = suspendedUserCount; } + + public long getPeriodStoreRevenue() { return periodStoreRevenue; } + public void setPeriodStoreRevenue(long periodStoreRevenue) { this.periodStoreRevenue = periodStoreRevenue; } + + public long getTotalStoreRevenue() { return totalStoreRevenue; } + public void setTotalStoreRevenue(long totalStoreRevenue) { this.totalStoreRevenue = totalStoreRevenue; } } diff --git a/backend/src/main/java/com/rit/canteen/sales/repository/OrderRepository.java b/backend/src/main/java/com/rit/canteen/sales/repository/OrderRepository.java index 2c2eaa34..bf7ddf11 100644 --- a/backend/src/main/java/com/rit/canteen/sales/repository/OrderRepository.java +++ b/backend/src/main/java/com/rit/canteen/sales/repository/OrderRepository.java @@ -25,6 +25,12 @@ public interface OrderRepository extends JpaRepository, JpaSpecific @Query("SELECT SUM(o.totalAmount) FROM Order o") BigDecimal getTotalRevenue(); + @Query("SELECT SUM(o.totalAmount) FROM Order o WHERE o.status = 'COMPLETED'") + BigDecimal getTotalCompletedRevenue(); + + @Query("SELECT SUM(o.totalAmount) FROM Order o WHERE o.status = 'COMPLETED' AND (o.orderType = 'POS' OR o.orderType = 'STORE_ORDER' OR o.paymentMethod = 'CASH')") + BigDecimal getCompletedStoreRevenue(); + @Query("SELECT COUNT(DISTINCT o.userId) FROM Order o WHERE o.createdAt >= :startOfDay") long countUniqueUsersToday(@Param("startOfDay") LocalDateTime startOfDay); @@ -34,6 +40,12 @@ public interface OrderRepository extends JpaRepository, JpaSpecific @Query("SELECT SUM(o.totalAmount) FROM Order o WHERE o.createdAt >= :start AND o.createdAt <= :end") BigDecimal getRevenuePerPeriod(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); + @Query("SELECT SUM(o.totalAmount) FROM Order o WHERE o.status = 'COMPLETED' AND o.createdAt >= :start AND o.createdAt <= :end") + BigDecimal getCompletedRevenuePerPeriod(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); + + @Query("SELECT SUM(o.totalAmount) FROM Order o WHERE o.status = 'COMPLETED' AND (o.orderType = 'POS' OR o.orderType = 'STORE_ORDER' OR o.paymentMethod = 'CASH') AND o.createdAt >= :start AND o.createdAt <= :end") + BigDecimal getCompletedStoreRevenuePerPeriod(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); + List findTop5ByOrderByCreatedAtDesc(); @Query("SELECT i.stallName, SUM(i.price * i.quantity), COUNT(DISTINCT o.id) " + diff --git a/backend/src/main/java/com/rit/canteen/sales/service/DashboardService.java b/backend/src/main/java/com/rit/canteen/sales/service/DashboardService.java index 97d347fd..96ce2373 100644 --- a/backend/src/main/java/com/rit/canteen/sales/service/DashboardService.java +++ b/backend/src/main/java/com/rit/canteen/sales/service/DashboardService.java @@ -147,14 +147,14 @@ public class DashboardService { LocalDateTime startOfYesterday = LocalDate.now(zone).minusDays(1).atStartOfDay(); LocalDateTime endOfYesterday = LocalDate.now(zone).minusDays(1).atTime(LocalTime.MAX); - System.out.println("[DIAGNOSTIC] Fetching Total Revenue..."); - BigDecimal totalRevenueRaw = tokenTransactionRepository.sumByType(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP); - System.out.println("[DIAGNOSTIC] Raw Total Revenue: " + totalRevenueRaw); + System.out.println("[DIAGNOSTIC] Fetching Total RITZ Spent..."); + BigDecimal totalRevenueRaw = tokenTransactionRepository.sumByType(com.rit.canteen.sales.model.TokenTransaction.TransactionType.SPEND); + System.out.println("[DIAGNOSTIC] Raw Total RITZ Spent: " + totalRevenueRaw); long totalSales = totalRevenueRaw != null ? totalRevenueRaw.longValue() : 0; - System.out.println("[DIAGNOSTIC] Fetching Period Revenue for range: " + from + " to " + to); - BigDecimal periodRevenueRaw = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP, from, to); - System.out.println("[DIAGNOSTIC] Raw Period Revenue: " + periodRevenueRaw); + System.out.println("[DIAGNOSTIC] Fetching Period RITZ Spent for range: " + from + " to " + to); + BigDecimal periodRevenueRaw = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.SPEND, from, to); + System.out.println("[DIAGNOSTIC] Raw Period RITZ Spent: " + periodRevenueRaw); long periodRevenue = periodRevenueRaw != null ? periodRevenueRaw.longValue() : 0; int activeOrders = (int) orderRepository.countByCreatedAtBetween(from, to); @@ -162,9 +162,9 @@ public class DashboardService { System.out.println("[REVENUE-TRACE] Active Orders in Range: " + activeOrders + " | Unique Customers: " + dailyCustomers); - BigDecimal todayRevenue = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP, startOfToday, endOfToday); - BigDecimal yesterdayRevenue = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP, startOfYesterday, endOfYesterday); - System.out.println("[DIAGNOSTIC] Today vs Yesterday: " + todayRevenue + " / " + yesterdayRevenue); + BigDecimal todayRevenue = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.SPEND, startOfToday, endOfToday); + BigDecimal yesterdayRevenue = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.SPEND, startOfYesterday, endOfYesterday); + System.out.println("[DIAGNOSTIC] Today vs Yesterday SPEND: " + todayRevenue + " / " + yesterdayRevenue); BigDecimal totalExpensesRaw = purchaseOrderRepository.getTotalPurchaseAmount(); long totalExpenses = totalExpensesRaw != null ? totalExpensesRaw.longValue() : 0; @@ -172,6 +172,18 @@ public class DashboardService { BigDecimal periodExpensesRaw = purchaseOrderRepository.getTotalPurchaseAmountInRange(from, to); long periodExpenses = periodExpensesRaw != null ? periodExpensesRaw.longValue() : 0; + BigDecimal periodPOSOrdersRaw = orderRepository.getCompletedStoreRevenuePerPeriod(from, to); + long periodPOSOrders = periodPOSOrdersRaw != null ? periodPOSOrdersRaw.longValue() : 0; + BigDecimal periodTopupsRaw = tokenTransactionRepository.sumByTypeInRange(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP, from, to); + long periodTopups = periodTopupsRaw != null ? periodTopupsRaw.longValue() : 0; + long periodStoreRevenue = periodPOSOrders + periodTopups; + + BigDecimal totalPOSOrdersRaw = orderRepository.getCompletedStoreRevenue(); + long totalPOSOrders = totalPOSOrdersRaw != null ? totalPOSOrdersRaw.longValue() : 0; + BigDecimal totalTopupsRaw = tokenTransactionRepository.sumByType(com.rit.canteen.sales.model.TokenTransaction.TransactionType.TOPUP); + long totalTopups = totalTopupsRaw != null ? totalTopupsRaw.longValue() : 0; + long totalStoreRevenue = totalPOSOrders + totalTopups; + long suspendedUserCount = userRepository.countByIsSuspended(true); double growth = 0; @@ -185,7 +197,7 @@ public class DashboardService { growth = 100.0; } - return new DashboardStats(totalSales, periodRevenue, activeOrders, dailyCustomers, growth, totalExpenses, periodExpenses, suspendedUserCount); + return new DashboardStats(totalSales, periodRevenue, activeOrders, dailyCustomers, growth, totalExpenses, periodExpenses, suspendedUserCount, periodStoreRevenue, totalStoreRevenue); } public ProcurementDashboardData getProcurementDashboardData() { diff --git a/counter-frontend/src/components/Layout.tsx b/counter-frontend/src/components/Layout.tsx index d34aa31c..2ef534b1 100644 --- a/counter-frontend/src/components/Layout.tsx +++ b/counter-frontend/src/components/Layout.tsx @@ -1,13 +1,10 @@ -import React from 'react'; import { Outlet, Link, useLocation, useNavigate } from 'react-router-dom'; import { - LayoutDashboard, ShoppingBag, History, Layers, Package, LogOut, - Menu, Bell, Search, User diff --git a/counter-frontend/src/pages/Categories.tsx b/counter-frontend/src/pages/Categories.tsx index d725bd4a..91f4ba48 100644 --- a/counter-frontend/src/pages/Categories.tsx +++ b/counter-frontend/src/pages/Categories.tsx @@ -1,11 +1,10 @@ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { Layers, Package, Search, Plus, Edit2, - Trash2, X, Check } from 'lucide-react'; diff --git a/counter-frontend/src/pages/Orders.tsx b/counter-frontend/src/pages/Orders.tsx index e34c7e8d..59d77025 100644 --- a/counter-frontend/src/pages/Orders.tsx +++ b/counter-frontend/src/pages/Orders.tsx @@ -501,7 +501,7 @@ const Orders: React.FC = () => {
Grand Total
-
β‚Ή{order.totalAmount.toFixed(2)}
+
πŸ…‘{order.totalAmount.toFixed(2)}
@@ -674,9 +674,9 @@ const Orders: React.FC = () => {
-
β‚Ή{(item.price * item.quantity).toLocaleString()}
+
πŸ…‘{(item.price * item.quantity).toLocaleString()}
- {item.quantity} x β‚Ή{item.price} + {item.quantity} x πŸ…‘{item.price}
@@ -744,7 +744,7 @@ const Orders: React.FC = () => {
Active Grand Total
-
β‚Ή{selectedOrder.totalAmount.toLocaleString()}
+
πŸ…‘{selectedOrder.totalAmount.toLocaleString()}
{selectedOrder.status === 'COMPLETED' ? 'Transaction Completed' : 'Transaction Pending Approval'}
@@ -828,7 +828,7 @@ const Orders: React.FC = () => {
{item.productName}
-
β‚Ή{item.price} each
+
πŸ…‘{item.price} each
@@ -849,7 +849,7 @@ const Orders: React.FC = () => {
-
β‚Ή{(item.price * item.quantity).toFixed(2)}
+
πŸ…‘{(item.price * item.quantity).toFixed(2)}
-
β‚Ή{product.price}
+
πŸ…‘{product.price}
)) ) : editSearchQuery ? ( @@ -910,7 +910,7 @@ const Orders: React.FC = () => {
New Order Total - β‚Ή{editTotal.toFixed(2)} + πŸ…‘{editTotal.toFixed(2)}
- {cart.length} items -
+
+

Current Order

+

+ +91 9043941910 +

+
+
+ + {cart.length} items +
{cart.length === 0 ? (
-
- -
-
-

Cart is empty

-

Select products to start billing

-
+
+ +
+
+

Cart is empty

+

Select products to start billing

+
) : ( cart.map((item) => ( @@ -286,9 +291,9 @@ const POS = () => {

{item.name}

-

β‚Ή{item.price} each

+

πŸ…‘{item.price} each

- {item.quantity} -
-

β‚Ή{item.price * item.quantity}

+

πŸ…‘{item.price * item.quantity}

@@ -323,22 +328,23 @@ const POS = () => {
-
- Total: - β‚Ή{total} -
- -
+ + + > + Complete Order + - + + + +

πŸ–¨οΈ Test QR β€” Print Preview

+ + +
+ + +
+
+
+ + + +
+ RIT Canteen +
+ Positeasy Β· Order Receipt +
+ ⚠️ TEST ORDER β€” NOT REAL +
+
+ + +
+ +
+ + +
+
+ Order # + #TEST +
+
+ Ref ID + ORD-TESTPRINT +
+
+ Customer + Test Customer +
+
+ Payment + Ritz Token +
+
+ Type + Dine-in +
+
+ +
+ + +
+
+ Samosa Γ— 1 + β‚Ή25 +
+
+ Masala Tea Γ— 2 + β‚Ή60 +
+
+ Veg Burger Γ— 1 + β‚Ή120 +
+
+ Total + β‚Ή205 +
+
+ +
+ + +
+ πŸ”’ This QR cannot be marked as Delivered.
+ Use for print quality & scan testing only. +
+ + + +
+ + + +

+ The QR encodes ORD-TESTPRINT. + The terminal will get a 404 β€” Order Not Found when it tries to look this up, + so it can never be accidentally marked as delivered. +

+ + + +