diff --git a/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java index ca5c5dc..e1c37d3 100644 --- a/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java +++ b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java @@ -59,7 +59,7 @@ public class CalculateWarehouseStatsAction { return articleIds.size(); } - private static class WarehouseStats { + public static class WarehouseStats { public int numArticles; public double efficiency; public double ratioUsedSlots; diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java index dbf7c6c..23c5955 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java @@ -1,17 +1,5 @@ package org.hso.ecommerce.controller.cronjob; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.annotation.PostConstruct; - import org.hso.ecommerce.action.booking.CreateBookingAction; import org.hso.ecommerce.action.cronjob.ReadSupplierDataAction; import org.hso.ecommerce.action.cronjob.ReadSupplierDataAction.ArticleIdentifier; @@ -28,11 +16,14 @@ import org.hso.ecommerce.entities.supplier.SupplierOrder; import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; import org.hso.ecommerce.repos.booking.BookingRepository; import org.hso.ecommerce.repos.cronjob.BackgroundJobRepository; +import org.hso.ecommerce.repos.dashboard.DashboardSummaryRepository; import org.hso.ecommerce.repos.shop.ArticleRepository; import org.hso.ecommerce.repos.shop.CustomerOrderRepository; import org.hso.ecommerce.repos.supplier.ArticleOfferRepository; import org.hso.ecommerce.repos.supplier.SupplierOrderRepository; import org.hso.ecommerce.repos.supplier.SupplierRepository; +import org.hso.ecommerce.repos.user.UserRepository; +import org.hso.ecommerce.repos.warehouse.SlotRepository; import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +35,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import javax.annotation.PostConstruct; +import java.sql.Timestamp; +import java.util.*; +import java.util.Map.Entry; + interface ICronjob { /** * Calculate the earliest cronjob execution time that happens after the given reference time. @@ -242,6 +238,9 @@ class CronjobController { @Autowired private final BackgroundJobRepository cronjobRepository = null; + @Autowired + final SlotRepository slotRepository = null; + @Autowired final ArticleRepository articleRepository = null; @@ -260,17 +259,24 @@ class CronjobController { @Autowired final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null; + @Autowired + final DashboardSummaryRepository dashboardSummaryRepository = null; + @Autowired final SupplierRepository supplierRepository = null; @Autowired final SupplierOrderRepository supplierOrderRepository = null; + @Autowired + final UserRepository userRepository = null; + private static Map getCronjobs() { HashMap map = new HashMap<>(); // Register all existing cronjobs map.put(BackgroundJob.JOB_REORDER, new Reorder()); + map.put(BackgroundJob.JOB_DASHBOARD, new DashboardCronjob()); return Collections.unmodifiableMap(map); } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/DashboardCronjob.java b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/DashboardCronjob.java new file mode 100644 index 0000000..8d1e9b7 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/DashboardCronjob.java @@ -0,0 +1,86 @@ +package org.hso.ecommerce.controller.cronjob; + +import org.hso.ecommerce.action.warehouse.CalculateWarehouseStatsAction; +import org.hso.ecommerce.entities.dashboard.DashboardSummary; +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; +import org.springframework.stereotype.Component; + +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class DashboardCronjob implements ICronjob { + + @Override + public Calendar nextExecution(Calendar reference) { + reference.add(Calendar.DAY_OF_MONTH, 1); + reference.set(Calendar.HOUR_OF_DAY, 0); + reference.set(Calendar.MINUTE, 0); + reference.set(Calendar.SECOND, 0); + reference.set(Calendar.MILLISECOND, 0); + return reference; + } + + @Override + public Calendar previousExecution(Calendar reference) { + reference.set(Calendar.HOUR_OF_DAY, 0); + reference.set(Calendar.MINUTE, 0); + reference.set(Calendar.SECOND, 0); + reference.set(Calendar.MILLISECOND, 0); + return reference; + } + + @Override + public void executeAt(Calendar time, CronjobController controller) { + + Calendar oneDayBefore = (Calendar) time.clone(); + oneDayBefore.add(Calendar.DAY_OF_MONTH, -1); + + DashboardSummary dashboardSummary = new DashboardSummary(); + + List entries = controller.slotRepository.findAll().stream().map( + s -> controller.warehouseBookingPositionSlotEntryRepository + .getBySlotNum(s.slotNum) + .orElseGet(() -> WarehouseBookingPositionSlotEntry.empty(null, s)) + ).collect(Collectors.toList()); + CalculateWarehouseStatsAction.WarehouseStats warehouseStats = new CalculateWarehouseStatsAction(entries).finish(); + + dashboardSummary.created = new java.sql.Date(time.getTimeInMillis()); + dashboardSummary.todaysCustomersOrders = nullToZero(getSales(oneDayBefore, time, controller)); + dashboardSummary.todaysNewCustomers = nullToZero(getNewUsers(oneDayBefore, time, controller)); + dashboardSummary.todaysWarehouseCapacity = warehouseStats.efficiency; + dashboardSummary.currentWarehouseCapacity = warehouseStats.ratioUsedSlots; + dashboardSummary.todaysSalesCent = nullToZero(getTurnover(oneDayBefore, time, controller)); + + controller.dashboardSummaryRepository.save(dashboardSummary); + } + + @Override + public String getDisplayName() { + return "Dashboard refresh"; + } + + private Integer getSales (Calendar begin, Calendar end, CronjobController controller) + { + return controller.customerOrderRepository.countOrdersInTimespan( + new Timestamp(begin.getTimeInMillis()), new Timestamp(end.getTimeInMillis())); + } + + private Integer getTurnover (Calendar begin, Calendar end, CronjobController controller) + { + return controller.customerOrderRepository.countTurnoverInTimespan( + new Timestamp(begin.getTimeInMillis()), new Timestamp(end.getTimeInMillis())); + } + + private Integer getNewUsers (Calendar begin, Calendar end, CronjobController controller) + { + return controller.userRepository.countUsersInTimespan( + new Timestamp(begin.getTimeInMillis()), new Timestamp(end.getTimeInMillis())); + } + + private int nullToZero(Integer input) { + return input == null ? 0 : input; + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/DashboardController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/DashboardController.java new file mode 100644 index 0000000..c3c22a2 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/DashboardController.java @@ -0,0 +1,25 @@ +package org.hso.ecommerce.controller.intern; + +import org.hso.ecommerce.entities.dashboard.DashboardSummary; +import org.hso.ecommerce.repos.dashboard.DashboardSummaryRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class DashboardController { + + @Autowired + private DashboardSummaryRepository dashboardSummaryRepository; + + @GetMapping("/intern/dashboardsummary") + public List getDashboardEntries() + { + List inTimespan = dashboardSummaryRepository.findInTimespan(PageRequest.of(0, 7) ); + return inTimespan; + } + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/dashboard/DashboardSummary.java b/prototype/src/main/java/org/hso/ecommerce/entities/dashboard/DashboardSummary.java index 9f68988..7f7b6a5 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/dashboard/DashboardSummary.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/dashboard/DashboardSummary.java @@ -15,11 +15,12 @@ public class DashboardSummary { @NotNull public java.sql.Date created; - public int todaysCustomers; + public int todaysNewCustomers; public int todaysCustomersOrders; public int todaysSuppliersOrders; public int todaysItemsSold; public int todaysSalesCent; public int totalWarehouseCapacity; - public int currentWarehouseCapacity; + public double currentWarehouseCapacity; + public double todaysWarehouseCapacity; } diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/dashboard/DashboardSummaryRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/dashboard/DashboardSummaryRepository.java new file mode 100644 index 0000000..7f57b71 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/repos/dashboard/DashboardSummaryRepository.java @@ -0,0 +1,20 @@ +package org.hso.ecommerce.repos.dashboard; + +import org.hso.ecommerce.entities.dashboard.DashboardSummary; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + + +@Repository +public interface DashboardSummaryRepository extends JpaRepository { + + @Query("SELECT ds FROM DashboardSummary ds ORDER BY ds.id DESC") + List findInTimespan( + Pageable pageable + ); + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java index 184831b..d0d21f5 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java @@ -25,4 +25,14 @@ public interface CustomerOrderRepository extends JpaRepository getOrdersByUserId(long userId); + @Query("SELECT COUNT(co.id) FROM CustomerOrder co WHERE co.created >= :begin AND co.created < :end") + Integer countOrdersInTimespan( + java.sql.Timestamp begin, java.sql.Timestamp end + ); + + @Query("SELECT SUM(co.totalGrossCent) FROM CustomerOrder co WHERE co.created >= :begin AND co.created < :end") + Integer countTurnoverInTimespan( + java.sql.Timestamp begin, java.sql.Timestamp end + ); + } \ No newline at end of file diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java index c48b9af..1daa1ac 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java @@ -13,6 +13,11 @@ public interface UserRepository extends JpaRepository { @Query("SELECT c FROM User c WHERE c.email = :email") Optional findByEmail(String email); + @Query("SELECT COUNT(c.id) FROM User c WHERE c.created >= :begin AND c.created < :end AND c.isEmployee = false") + Integer countUsersInTimespan( + java.sql.Timestamp begin, java.sql.Timestamp end + ); + @Query("SELECT count(*) FROM User WHERE isEmployee = true") Optional numberOfEmployees(); } diff --git a/prototype/src/main/resources/application.properties b/prototype/src/main/resources/application.properties index aee1c7d..7c62f1b 100644 --- a/prototype/src/main/resources/application.properties +++ b/prototype/src/main/resources/application.properties @@ -22,3 +22,8 @@ spring.servlet.multipart.max-request-size=10MB # EMBEDDED SERVER CONFIGURATION (ServerProperties) server.address=::1 server.port=8080 + +spring.thymeleaf.prefix=file:src/main/resources/templates/ +spring.thymeleaf.cache=false +spring.resources.static-locations=file:src/main/resources/static/ +spring.resources.cache=false \ No newline at end of file diff --git a/prototype/src/main/resources/templates/intern/index.html b/prototype/src/main/resources/templates/intern/index.html index 95997d7..1b0bb49 100644 --- a/prototype/src/main/resources/templates/intern/index.html +++ b/prototype/src/main/resources/templates/intern/index.html @@ -6,8 +6,8 @@ @@ -107,7 +106,12 @@

Verkäufe (Anzahl)

@@ -116,7 +120,12 @@

Verkäufe (Umsatz)

@@ -125,7 +134,12 @@

Neukunden

@@ -139,7 +153,12 @@

Lagerauslastung

@@ -148,7 +167,12 @@

Lagereffizienz