Skip to content

Commit a32739c

Browse files
authored
Merge pull request #59 from UdL-EPS-SoftArch/Inventory
Inventory New Functionalities
2 parents dd33136 + e313d57 commit a32739c

12 files changed

Lines changed: 133 additions & 66 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class Inventory {
7070
description
7171
location
7272
totalStock
73+
type: [WAREHOUSE, SHELF, FRIDGE...]
74+
status: [ACTIVE, FULL, MAINTENANCE, CLOSED]
75+
capacity
76+
lastUpdated
7377
}
7478
class Category {
7579
name

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
<path>
133133
<groupId>org.projectlombok</groupId>
134134
<artifactId>lombok</artifactId>
135-
<version>1.18.34</version>
135+
<version>1.18.36</version>
136136
</path>
137137
</annotationProcessorPaths>
138138
</configuration>

src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exce
6060
.requestMatchers(HttpMethod.PATCH, "/inventories/**").hasRole("BUSINESS")
6161
.requestMatchers(HttpMethod.DELETE, "/inventories/**").hasRole("BUSINESS")
6262

63+
.requestMatchers(HttpMethod.POST, "/categories").hasRole("ADMIN")
64+
6365
// Identidad (Cualquiera Autenticado)
6466
.requestMatchers(HttpMethod.GET, "/identity").authenticated()
6567

src/main/java/cat/udl/eps/softarch/demo/domain/Admin.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
public class Admin extends User {
1818

1919
@Override
20-
@Transient
21-
@JsonValue(value = false)
20+
@JsonValue(false)
2221
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
2322
public Collection<? extends GrantedAuthority> getAuthorities() {
2423
return AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN");

src/main/java/cat/udl/eps/softarch/demo/domain/Inventory.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,52 @@ public class Inventory extends UriEntity<Long> {
2929
@ManyToOne
3030
private Business business;
3131

32+
@Enumerated(EnumType.STRING)
33+
private InventoryType type;
3234

35+
@Enumerated(EnumType.STRING)
36+
private InventoryStatus status;
37+
38+
private Integer capacity;
39+
40+
private java.time.LocalDateTime lastUpdated;
41+
42+
@OneToMany(mappedBy = "inventory", fetch = FetchType.LAZY)
43+
@lombok.ToString.Exclude
44+
@lombok.EqualsAndHashCode.Exclude
45+
@com.fasterxml.jackson.annotation.JsonIgnore
46+
private List<Product> products;
47+
48+
/**
49+
* Calculates the real total stock from the list of products.
50+
* Returns 0 if the product list is not loaded/initialized.
51+
*/
52+
public int getCalculatedTotalStock() {
53+
if (products == null) {
54+
return 0;
55+
}
56+
return products.stream()
57+
.mapToInt(Product::getStock)
58+
.sum();
59+
}
60+
61+
/**
62+
* Checks if the inventory is full based on capacity.
63+
*/
64+
public boolean isFull() {
65+
if (capacity == null || capacity == 0)
66+
return false;
67+
return getCalculatedTotalStock() >= capacity;
68+
}
69+
70+
/**
71+
* Updates the local totalStock field to match the calculated reality.
72+
*/
73+
public void syncTotalStock() {
74+
if (products != null && !products.isEmpty()) {
75+
this.totalStock = products.stream()
76+
.mapToInt(Product::getStock)
77+
.sum();
78+
}
79+
}
3380
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package cat.udl.eps.softarch.demo.domain;
2+
3+
public enum InventoryStatus {
4+
ACTIVE,
5+
FULL,
6+
MAINTENANCE,
7+
CLOSED
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package cat.udl.eps.softarch.demo.domain;
2+
3+
public enum InventoryType {
4+
WAREHOUSE,
5+
SHELF,
6+
FRIDGE,
7+
DISPLAY,
8+
BACKROOM
9+
}

src/main/java/cat/udl/eps/softarch/demo/handler/CategoryEventHandler.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/main/java/cat/udl/eps/softarch/demo/handler/InventoryEventHandler.java

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import cat.udl.eps.softarch.demo.domain.Business;
44
import cat.udl.eps.softarch.demo.domain.Inventory;
5+
import cat.udl.eps.softarch.demo.domain.InventoryStatus;
6+
import cat.udl.eps.softarch.demo.domain.InventoryType;
57
import cat.udl.eps.softarch.demo.repository.InventoryRepository;
68
import org.slf4j.Logger;
79
import org.slf4j.LoggerFactory;
10+
import java.time.LocalDateTime;
811
import org.springframework.data.rest.core.annotation.*;
912
import org.springframework.security.access.AccessDeniedException;
1013
import org.springframework.security.core.Authentication;
@@ -14,7 +17,6 @@
1417
@Component
1518
@RepositoryEventHandler
1619
public class InventoryEventHandler {
17-
1820
private final Logger logger = LoggerFactory.getLogger(InventoryEventHandler.class);
1921
private final InventoryRepository inventoryRepository;
2022

@@ -25,29 +27,49 @@ public InventoryEventHandler(InventoryRepository inventoryRepository) {
2527
@HandleBeforeCreate
2628
public void handleBeforeCreate(Inventory inventory) {
2729
logger.info("Before creating inventory: {}", inventory);
28-
2930
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
30-
31-
// 1. Validació
3231
if (auth == null || !auth.isAuthenticated()) {
3332
throw new AccessDeniedException("Must be logged in to create inventory");
3433
}
3534

36-
37-
Object principal = auth.getPrincipal();
38-
39-
if (principal instanceof Business) {
40-
Business business = (Business) principal;
35+
if (auth.getPrincipal() instanceof Business business) {
4136
inventory.setBusiness(business);
4237
} else {
43-
throw new AccessDeniedException("Only Business accounts can create inventories. You are: " + principal.getClass().getSimpleName());
38+
throw new AccessDeniedException("Only Business accounts can create inventories");
4439
}
40+
41+
if (inventory.getStatus() == null)
42+
inventory.setStatus(InventoryStatus.ACTIVE);
43+
if (inventory.getType() == null)
44+
inventory.setType(InventoryType.WAREHOUSE);
45+
inventory.setLastUpdated(LocalDateTime.now());
4546
}
4647

4748
@HandleBeforeSave
4849
public void handleBeforeSave(Inventory inventory) {
4950
logger.info("Before updating inventory: {}", inventory);
5051
checkOwnership(inventory);
52+
53+
// ONLY sync if products are loaded.
54+
// If not loaded, respect the totalStock value coming from the UI/request.
55+
if (inventory.getProducts() != null && !inventory.getProducts().isEmpty()) {
56+
inventory.syncTotalStock();
57+
}
58+
59+
// Capacity logic
60+
if (inventory.getCapacity() != null && inventory.getCapacity() > 0) {
61+
if (inventory.getTotalStock() >= inventory.getCapacity()) {
62+
if (inventory.getStatus() != InventoryStatus.CLOSED
63+
&& inventory.getStatus() != InventoryStatus.MAINTENANCE) {
64+
inventory.setStatus(InventoryStatus.FULL);
65+
logger.info("Inventory {} reached capacity. Status set to FULL.", inventory.getId());
66+
}
67+
} else if (inventory.getStatus() == InventoryStatus.FULL) {
68+
inventory.setStatus(InventoryStatus.ACTIVE);
69+
logger.info("Inventory {} has space. Status restored to ACTIVE.", inventory.getId());
70+
}
71+
}
72+
inventory.setLastUpdated(LocalDateTime.now());
5173
}
5274

5375
@HandleBeforeDelete
@@ -59,13 +81,10 @@ public void handleBeforeDelete(Inventory inventory) {
5981
private void checkOwnership(Inventory inventory) {
6082
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
6183
String currentUsername = auth.getName();
62-
6384
if (inventory.getBusiness() != null && !inventory.getBusiness().getUsername().equals(currentUsername)) {
64-
boolean isAdmin = auth.getAuthorities().stream()
65-
.anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"));
66-
85+
boolean isAdmin = auth.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"));
6786
if (!isAdmin) {
68-
throw new AccessDeniedException("You can only modify your own inventory");
87+
throw new AccessDeniedException("You are not the owner of this inventory");
6988
}
7089
}
7190
}

src/main/resources/application-flyio.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
allowed-origins: "https://react-template.netlify.app,https://deploy-preview-*--react-template.netlify.app"
1+
allowed-origins: "https://mycoffee.vercel.app,https://mycoffee-*.vercel.app"
22

33
logging:
44
level:

0 commit comments

Comments
 (0)