Skip to content

Commit 270c698

Browse files
author
MartinTCode
committed
feat: Enhance loan processing with validation checks and service integration
1 parent 8c5d533 commit 270c698

File tree

3 files changed

+126
-32
lines changed

3 files changed

+126
-32
lines changed

src/main/java/com/javafullstacklibrary/frontend/borrowerControllers/LoanReceiptBorrowerController.java

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,10 @@
99

1010
import com.javafullstacklibrary.model.Item;
1111
import com.javafullstacklibrary.model.ItemCopy;
12-
import com.javafullstacklibrary.model.LibraryUser;
1312
import com.javafullstacklibrary.utils.MenuNavigationHelper;
1413
import com.javafullstacklibrary.utils.PendingTransactionManager;
15-
import com.javafullstacklibrary.dao.LoanDAO;
1614
import com.javafullstacklibrary.utils.UserSession;
1715

18-
import jakarta.persistence.EntityManager;
19-
import jakarta.persistence.EntityManagerFactory;
20-
import jakarta.persistence.Persistence;
21-
2216
import java.time.LocalDate;
2317
import java.util.List;
2418

@@ -36,13 +30,9 @@ public class LoanReceiptBorrowerController {
3630
@FXML
3731
private Button printLoanRecieptBorrower;
3832

39-
private LoanDAO loanDAO;
40-
private EntityManager entityManager;
33+
4134

4235
public void initialize() {
43-
EntityManagerFactory emf = Persistence.createEntityManagerFactory("libraryPU");
44-
this.entityManager = emf.createEntityManager();
45-
this.loanDAO = new LoanDAO(entityManager);
4636
displayLoanReceipt();
4737
}
4838

@@ -82,19 +72,10 @@ private void displayLoanReceipt() {
8272
}
8373

8474
// Process the loans in the database
85-
processLoans(loanedItems);
86-
}
87-
88-
private void processLoans(List<ItemCopy> itemCopies) {
89-
// do this with the DOA:
90-
LibraryUser loaner = UserSession.getCurrentUser();
91-
for (ItemCopy itemCopy : itemCopies) {
92-
loanDAO.save(itemCopy, loaner, getReturnDateByItemCopy(itemCopy));
93-
}
94-
// Clear the pending loans list after successful processing
9575
PendingTransactionManager.getInstance().clearPending();
9676
}
9777

78+
9879
private LocalDate getReturnDateByItemCopy(ItemCopy itemCopy) {
9980
// First extract the item from the ItemCopy
10081
Item item = itemCopy.getItem();

src/main/java/com/javafullstacklibrary/frontend/borrowerControllers/LoanViewBorrowerController.java

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import com.javafullstacklibrary.utils.MenuNavigationHelper;
1616
import com.javafullstacklibrary.utils.PendingTransactionManager;
1717
import com.javafullstacklibrary.utils.UserSession;
18-
1918
import java.util.List;
2019

2120
public class LoanViewBorrowerController {
@@ -41,6 +40,7 @@ public class LoanViewBorrowerController {
4140
@FXML
4241
private Label statusLabel;
4342

43+
4444
public void initialize() {
4545
loadPendingLoans();
4646
}
@@ -135,8 +135,12 @@ private void clickedAddLoanButton() {
135135
return;
136136
}
137137

138-
if (!loanValidationService.canLoanMore(UserSession.getCurrentUser(), PendingTransactionManager.getInstance())) {
139-
showErrorMessage("You have reached the maximum number of pending loans allowed for your user type.");
138+
// Use service to validate if user can add more items to pending
139+
ValidationResult<Void> addValidation = loanValidationService.validateAddToPending(
140+
UserSession.getCurrentUser(), PendingTransactionManager.getInstance());
141+
142+
if (!addValidation.isSuccess()) {
143+
showErrorMessage(addValidation.getMessage());
140144
return;
141145
}
142146

@@ -152,14 +156,36 @@ private void clickedAddLoanButton() {
152156

153157
@FXML
154158
private void clickedConfirmLoansButtonBorrower() {
155-
List<ItemCopy> pendingLoans = PendingTransactionManager.getInstance().getPending();
156-
157-
if (pendingLoans.isEmpty()) {
158-
showErrorMessage("No items selected for loan");
159-
return;
159+
try (LoanValidationService loanValidationService = new LoanValidationService()) {
160+
// Use service to validate loan confirmation
161+
ValidationResult<Void> confirmationResult = loanValidationService.validateLoanConfirmation(
162+
UserSession.getCurrentUser(), PendingTransactionManager.getInstance());
163+
164+
if (!confirmationResult.isSuccess()) {
165+
showErrorMessage(confirmationResult.getMessage());
166+
return;
167+
}
168+
169+
List<ItemCopy> pendingLoans = PendingTransactionManager.getInstance().getPending();
170+
171+
// Use service to process the loans
172+
ValidationResult<Void> processResult = loanValidationService.processLoans(
173+
pendingLoans, UserSession.getCurrentUser());
174+
175+
if (!processResult.isSuccess()) {
176+
showErrorMessage(processResult.getMessage());
177+
return;
178+
}
179+
180+
// Clear pending loans after successful processing
181+
PendingTransactionManager.getInstance().clearPending();
182+
183+
showSuccessMessage("Loans confirmed successfully");
184+
MenuNavigationHelper.buttonClickBorrower(mainPane, "LoanReceipt");
185+
} catch (Exception e) {
186+
System.err.println("Error processing loans: " + e.getMessage());
187+
showErrorMessage("Error processing loan request");
160188
}
161-
162-
MenuNavigationHelper.buttonClickBorrower(mainPane, "LoanReceipt");
163189
}
164190

165191
/**
@@ -187,7 +213,7 @@ private void addItemToLoanContainer(ItemCopy itemCopy) {
187213
itemContainer.getChildren().addAll(itemLabel, removeButton);
188214
loanContainer.getChildren().add(itemContainer);
189215
}
190-
216+
191217
private void clearStatusMessage() {
192218
statusLabel.setVisible(false);
193219
statusLabel.setManaged(false);

src/main/java/com/javafullstacklibrary/services/LoanValidationService.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.javafullstacklibrary.dao.ItemCopyDAO;
44
import com.javafullstacklibrary.dao.LoanDAO;
55

6+
import com.javafullstacklibrary.model.Item;
67
import com.javafullstacklibrary.model.ItemCopy;
78
import com.javafullstacklibrary.model.Journal;
89
import com.javafullstacklibrary.model.LibraryUser;
@@ -12,6 +13,8 @@
1213
import jakarta.persistence.EntityManagerFactory;
1314
import jakarta.persistence.Persistence;
1415

16+
import java.time.LocalDate;
17+
import java.util.List;
1518
import java.util.Optional;
1619

1720
public class LoanValidationService implements AutoCloseable {
@@ -96,6 +99,90 @@ public ValidationResult<ItemCopy> validateBarcodeForLoan(String barcode) {
9699
return ValidationResult.success(itemCopy);
97100
}
98101

102+
/**
103+
* Validates if the user can confirm all pending loans without exceeding their limit
104+
* @param libraryUser The user requesting the loans
105+
* @param pendingTransactionManager The pending transaction manager containing items to loan
106+
* @return ValidationResult indicating success or failure with appropriate message
107+
*/
108+
public ValidationResult<Void> validateLoanConfirmation(LibraryUser libraryUser, PendingTransactionManager pendingTransactionManager) {
109+
if (pendingTransactionManager.getPending().isEmpty()) {
110+
return ValidationResult.failure("No items selected for loan");
111+
}
112+
113+
int maxLoans = loanDAO.getMaxLoansByUser(libraryUser);
114+
int currentActiveLoans = Math.toIntExact(loanDAO.countActiveLoansByUser(libraryUser));
115+
int pendingCount = pendingTransactionManager.getPendingCount();
116+
117+
if (maxLoans != -1 && (currentActiveLoans + pendingCount) > maxLoans) {
118+
return ValidationResult.failure(String.format(
119+
"Cannot confirm loans: would exceed maximum limit of %d loans (current: %d, pending: %d)",
120+
maxLoans, currentActiveLoans, pendingCount));
121+
}
122+
123+
return ValidationResult.success(null);
124+
}
125+
126+
/**
127+
* Validates if a user can add one more item to their pending loans
128+
* @param libraryUser The user requesting to add an item
129+
* @param pendingTransactionManager The pending transaction manager
130+
* @return ValidationResult indicating success or failure
131+
*/
132+
public ValidationResult<Void> validateAddToPending(LibraryUser libraryUser, PendingTransactionManager pendingTransactionManager) {
133+
int maxLoans = loanDAO.getMaxLoansByUser(libraryUser);
134+
int currentActiveLoans = Math.toIntExact(loanDAO.countActiveLoansByUser(libraryUser));
135+
int pendingCount = pendingTransactionManager.getPendingCount();
136+
137+
if (maxLoans != -1 && (currentActiveLoans + pendingCount + 1) > maxLoans) {
138+
return ValidationResult.failure(String.format(
139+
"You have reached the maximum number of loans allowed for your user type (%d)", maxLoans));
140+
}
141+
142+
return ValidationResult.success(null);
143+
}
144+
145+
/**
146+
* Processes a list of pending loans by creating loan records in the database
147+
* @param itemCopies List of ItemCopy objects to loan
148+
* @param libraryUser The user taking out the loans
149+
* @return ValidationResult indicating success or failure with appropriate message
150+
*/
151+
public ValidationResult<Void> processLoans(List<ItemCopy> itemCopies, LibraryUser libraryUser) {
152+
if (itemCopies == null || itemCopies.isEmpty()) {
153+
return ValidationResult.failure("No items to process for loan");
154+
}
155+
156+
if (libraryUser == null) {
157+
return ValidationResult.failure("Library user is required for processing loans");
158+
}
159+
160+
try {
161+
// Process each loan
162+
for (ItemCopy itemCopy : itemCopies) {
163+
LocalDate returnDate = getReturnDateByItemCopy(itemCopy);
164+
loanDAO.save(itemCopy, libraryUser, returnDate);
165+
}
166+
167+
return ValidationResult.success(null);
168+
} catch (IllegalStateException e) {
169+
return ValidationResult.failure("Loan processing failed: " + e.getMessage());
170+
} catch (Exception e) {
171+
return ValidationResult.failure("An error occurred while processing loans");
172+
}
173+
}
174+
175+
/**
176+
* Calculates the return date for an item copy based on its maximum loan time
177+
* @param itemCopy The ItemCopy to calculate return date for
178+
* @return LocalDate representing when the item should be returned
179+
*/
180+
private LocalDate getReturnDateByItemCopy(ItemCopy itemCopy) {
181+
Item item = itemCopy.getItem();
182+
int daysToAdd = item.getMaxLoanTimeDays();
183+
return LocalDate.now().plusDays(daysToAdd);
184+
}
185+
99186
@Override
100187
public void close() {
101188
if (em != null && em.isOpen()) {

0 commit comments

Comments
 (0)