Skip to content

Commit

Permalink
updates - link with fe
Browse files Browse the repository at this point in the history
  • Loading branch information
drseveriano committed Nov 12, 2024
1 parent fed47e1 commit 97dc8f8
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 29 deletions.
15 changes: 12 additions & 3 deletions src/main/java/controller/ItemController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ItemController {
ItemService itemService;

@POST
@Path("create")
@Path("/create")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({Role.ROLE_ADMIN, Role.ROLE_GENERIC})
Expand All @@ -30,10 +30,19 @@ public Response createItem(@RequestBody ItemRequest itemRequest) {
}

@GET
@Path("/inventory")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({Role.ROLE_ADMIN, Role.ROLE_GENERIC, Role.ROLE_READ_ONLY})
public Response getAllItems() {
return Response.ok(itemService.findAll()).build();
public Response getAllInventoryItems() {
return Response.ok(itemService.findAllInventory()).build();
}

@GET
@Path("/stock")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({Role.ROLE_ADMIN, Role.ROLE_GENERIC, Role.ROLE_READ_ONLY})
public Response getAllStockItems() {
return Response.ok(itemService.findAllStock()).build();
}

}
6 changes: 6 additions & 0 deletions src/main/java/enums/ItemType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package enums;

public enum ItemType {
INVENTORY,
STOCK
}
6 changes: 1 addition & 5 deletions src/main/java/model/Inventory.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ public class Inventory extends AuditEntity implements Serializable {
private InventoryType inventoryType;

@Column(nullable = false)
private double quantity = 0;

private double minQuantity = 0;

private boolean alertLowStock = false;
private double quantity = 0.0;

@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Unit unit;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/model/Item.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package model;

import enums.ItemType;
import jakarta.persistence.*;
import lombok.*;

Expand Down Expand Up @@ -29,12 +30,22 @@ public class Item extends AuditEntity implements Serializable {
//e.g. Cereal, Beer, Keg, etc.
private ItemCategory category;

@Column(name = "item_type")
private ItemType itemType;

private String brand;

private String description;

private String notes;

@Column(nullable = false)
private double quantity = 0;

private double minQuantity = 0;

private boolean alertLowStock = false;

private boolean deprecated = false;

}
3 changes: 1 addition & 2 deletions src/main/java/records/InventoryManualRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.math.BigDecimal;

public record InventoryManualRequest(Integer itemId, Supplier supplier, Warehouse warehouse,
InventoryType inventoryType, int quantity,
int minQuantity, boolean alertLowStock, Integer unitId,
InventoryType inventoryType, double quantity, Integer unitId,
BigDecimal costPrice, String notes, String batch, BigDecimal salePrice) {
}
5 changes: 4 additions & 1 deletion src/main/java/records/ItemRequest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package records;

import enums.ItemType;

public record ItemRequest(String code, String name, Integer categoryId, String brand, String description,
String notes, boolean deprecated) {
String notes, ItemType itemType, double quantity, double minQuantity, boolean alertLowStock,
boolean deprecated) {
}
2 changes: 1 addition & 1 deletion src/main/java/records/LoginResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import lombok.Builder;

@Builder
public record LoginResponse(String token, String username, String email) {
public record LoginResponse(String token, String username, String email, String role) {
}
106 changes: 96 additions & 10 deletions src/main/java/service/AggregatorService.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package service;

import enums.InventoryType;
import enums.ItemType;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import model.Inventory;
import records.StatisticCard;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@ApplicationScoped
public class AggregatorService {
Expand All @@ -18,11 +23,15 @@ public class AggregatorService {
@Inject
private InventoryService inventoryService;

@Inject
private ItemService itemService;

public List<StatisticCard> getStatisticsForInventoryPage() {
return List.of(
createStatisticCard("Inventory Items", getTotalNumberOfItems(), "ri-box-1-fill", "primary", false),
createStatisticCard("Purchase Orders (Pendind Delivery)", getTotalNumberOfPurchaseOrdersPendingDelivery(), "ri-ship-2-line", "info", false),
createStatisticCard("Inventory Price", getInventoryTotalPrice(), "ri-money-euro-circle-line", "info", true),
createStatisticCard("(Average) Inventory Price", getInventoryTotalPrice(), "ri-money-euro-circle-line", "primary", true),
createStatisticCard("Total Amount of Cereal", getTotalWeightOfCereal(), "ri-scales-line", "warning", false),
createStatisticCard("Inventory Alerts", getTotalNumberOfInventoryAlerts(), "ri-alert-line", "error", false)
);
}
Expand Down Expand Up @@ -73,25 +82,89 @@ private String getTotalNumberOfPurchaseOrdersPendingDelivery() {
return "" + 0L;
}

//#TODO :: IMPLEMENT SERVICE
private String getTotalNumberOfInventoryAlerts() {
if (warehouseService.getDefaultWarehouse().isPresent()) {
return "" + itemService.findAllInventory().stream().filter(item ->
item.isAlertLowStock() && item.getQuantity() < item.getMinQuantity()
).count();
}

return "" + 0L;
}

//REVIEW
private String getInventoryTotalPrice() {
if (warehouseService.getDefaultWarehouse().isPresent()) {
return "" + inventoryService.findAll().stream()
.filter(inventory -> !inventory.getInventoryType().equals(InventoryType.FINISHED_PRODUCT))
.map(inventory -> inventory.getCostPrice()
.multiply(BigDecimal.valueOf(inventory.getQuantity()))
.setScale(2, RoundingMode.HALF_UP))
.reduce(BigDecimal.ZERO, BigDecimal::add)
.setScale(2, RoundingMode.HALF_UP);
// Step 1: Get all inventories from the inventory service
List<Inventory> allInventories = inventoryService.findAll();

// Step 2: Group positive inventory entries by item code and calculate average cost price
Map<String, BigDecimal> itemCodeToAvgCostPrice = new HashMap<>();

// Group positive inventories by itemCode and accumulate the cost and quantity
Map<String, List<Inventory>> positiveInventoryGroupedByItemCode = allInventories.stream()
.filter(inventory -> inventory.getQuantity() > 0) // Only include positive inventories
.collect(Collectors.groupingBy(inventory -> inventory.getItem().getCode()));

// Step 3: Calculate the average cost price for each item code
for (Map.Entry<String, List<Inventory>> entry : positiveInventoryGroupedByItemCode.entrySet()) {
String itemCode = entry.getKey();
List<Inventory> positiveInventories = entry.getValue();

// Calculate total cost and total quantity for the item (positive inventories)
BigDecimal totalCost = BigDecimal.ZERO;
BigDecimal totalQuantity = BigDecimal.ZERO;

for (Inventory inventory : positiveInventories) {
totalCost = totalCost.add(inventory.getCostPrice().multiply(BigDecimal.valueOf(inventory.getQuantity())));
totalQuantity = totalQuantity.add(BigDecimal.valueOf(inventory.getQuantity()));
}

// Calculate the average cost price, if totalQuantity is greater than zero
if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal avgCostPrice = totalCost.divide(totalQuantity, 2, RoundingMode.HALF_UP);
itemCodeToAvgCostPrice.put(itemCode, avgCostPrice);
} else {
itemCodeToAvgCostPrice.put(itemCode, BigDecimal.ZERO); // Default to zero if no positive quantities
}
}

// Step 4: Sum all quantities (positive and negative) by item code and calculate total cost based on average cost price
BigDecimal totalInventoryCost = BigDecimal.ZERO;

Map<String, BigDecimal> itemCodeToTotalQuantity = new HashMap<>();

// Sum quantities for both positive and negative inventories by item code
for (Inventory inventory : allInventories) {
String itemCode = inventory.getItem().getCode();
BigDecimal quantity = BigDecimal.valueOf(inventory.getQuantity());

// Sum the quantities for each item code (positive and negative)
itemCodeToTotalQuantity.put(itemCode,
itemCodeToTotalQuantity.getOrDefault(itemCode, BigDecimal.ZERO).add(quantity));
}

// Calculate the total inventory cost by multiplying total quantity by average cost price
for (Map.Entry<String, BigDecimal> entry : itemCodeToTotalQuantity.entrySet()) {
String itemCode = entry.getKey();
BigDecimal totalQuantity = entry.getValue();
BigDecimal avgCostPrice = itemCodeToAvgCostPrice.getOrDefault(itemCode, BigDecimal.ZERO);

// Multiply total quantity by average cost price to get total cost for this item
BigDecimal totalCostForItem = totalQuantity.multiply(avgCostPrice);

// Add the cost for this item to the total inventory cost
totalInventoryCost = totalInventoryCost.add(totalCostForItem);
}

// Step 5: Return the total cost of inventory
return totalInventoryCost.setScale(2, RoundingMode.HALF_UP).toString();
}

return "0";
return "0"; // Return "0" if no default warehouse is found
}


private String getStockPrice() {
if (warehouseService.getDefaultWarehouse().isPresent()) {
return "" + inventoryService.findAll().stream()
Expand Down Expand Up @@ -120,4 +193,17 @@ private String getPotentialProfit() {

return "0";
}

private String getTotalWeightOfCereal() {
if (warehouseService.getDefaultWarehouse().isPresent()) {
return "" + itemService.findAllInventory().stream()

Check warning on line 199 in src/main/java/service/AggregatorService.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Concatenation with empty string

Empty string in concatenation
.filter(item -> item.getItemType().equals(ItemType.INVENTORY)
&& item.getCategory().getName().equals("Cereal"))
.map(item -> BigDecimal.valueOf(item.getQuantity()))
.reduce(BigDecimal.ZERO, BigDecimal::add)
.setScale(2, RoundingMode.HALF_UP) + " KG";
}

return "0";
}
}
15 changes: 10 additions & 5 deletions src/main/java/service/InventoryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import java.util.List;

/// TODO :: CONTROLAR ENTRADAS E SAIDA DE PRODUTO ACABADO COM BATCH

@ApplicationScoped
public class InventoryService {

Expand All @@ -23,19 +25,22 @@ public class InventoryService {

@Transactional
public boolean createManualEntryOnInventory(InventoryManualRequest request) {
Inventory.builder()
System.out.println(request);

Inventory newEntry = Inventory.builder()
.salePrice(request.salePrice())
.supplier(request.supplier())
.supplier(request.supplier().id == -1 ? null : request.supplier())
.batch(request.batch())
.warehouse(request.warehouse())
.item(itemService.findById(request.itemId()))
.inventoryType(request.inventoryType())
.unit(unitService.findById(request.unitId()))
.alertLowStock(request.alertLowStock())
.quantity(request.quantity())
.minQuantity(request.minQuantity())
.costPrice(request.costPrice())
.build().persistAndFlush();
.build();

newEntry.persistAndFlush();
itemService.updateQuantity(newEntry);

return true;
}
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/service/ItemService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package service;

import enums.ItemType;
import exceptions.ItemAlreadyExists;
import io.smallrye.common.constraint.NotNull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import model.Inventory;
import model.Item;
import records.ItemRequest;

Expand All @@ -22,20 +24,33 @@ public boolean createItem(@NotNull ItemRequest item) {
throw new ItemAlreadyExists(item.code());

Item.builder()
.itemType(item.itemType())
.code(item.code())
.name(item.name())
.brand(item.brand())
.category(itemCategoryService.findById(item.categoryId()))
.description(item.description())
.notes(item.notes())
.deprecated(item.deprecated())
.minQuantity(item.minQuantity())
.quantity(item.quantity())
.alertLowStock(item.alertLowStock())
.build().persistAndFlush();

return true;
}

public List<Item> findAll() {
return Item.findAll().list();
@Transactional
public void updateQuantity(Inventory inventory) {
inventory.getItem().setQuantity(inventory.getItem().getQuantity() + inventory.getQuantity());
inventory.getItem().persistAndFlush();
}

public List<Item> findAllInventory() {
return Item.find("itemType", ItemType.INVENTORY).list();
}
public List<Item> findAllStock() {
return Item.find("itemType", ItemType.STOCK).list();
}

public Item findById(Integer id) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private LoginResponse buildResponse(User user) {
.sign())
.username(user.getFirstName() + " " + user.getLastName())
.email(user.getEmail())
.role(user.getRoles())
.build();
}

Expand Down

0 comments on commit 97dc8f8

Please sign in to comment.