As part of a team of six, I developed a full-stack online game store for a fictional client, designed to manage game inventory, user accounts, and purchases. The project featured a responsive user interface, thorough test suite, and role-based account permissions. Following industry best practices, the system was built with a focus on reliability, usability, and scalability, achieving comprehensive test coverage and meeting all specified functional and non-functional requirements.
/**
* Processes the purchase of all items in a customer's cart.
*
* @param username The username of the customer making the purchase.
* @return Order if the purchase is successful.
*/
@Transactional
public Order purchaseCart(String username) {
// Retrieve customer details by username
Customer customer = customerRepo.findByUsername(username);
if (customer == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No such customer with username exists");
}
// Check if customer has payment information
PaymentInformation paymentInformation = customer.getPaymentInformation();
if (paymentInformation == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer does not have valid payment information");
}
// Validate postal code format for billing address
if (!paymentInformation.getBillingAddress().getPostalCode()
.matches("^[A-Za-z][0-9][A-Za-z][0-9][A-Za-z][0-9]$")) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
"Customer address postal code information is not valid");
}
// Validate credit card number and CVV code
if (paymentInformation.getCardNumber().length() != 16) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer does not have valid credit card number");
}
if (Integer.toString(paymentInformation.getCvvCode()).length() != 3) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer does not have valid CVV code");
}
// Check if credit card is expired
Date currentDate = new Date(System.currentTimeMillis());
if (paymentInformation.getExpiryDate().before(currentDate)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer credit card is expired");
}
// Retrieve all items in the customer's cart
CartItem[] cartItems = getCartItems(customer);
if (cartItems == null || cartItems.length <= 0) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer cart is empty");
}
// Check if there is enough stock for each game in the cart
Game game;
for (int i = 0; i < cartItems.length; i++) {
game = cartItems[i].getKey().getGame();
if (cartItems[i].getQuantity() > game.getStock()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
String.format("There is not enough stock of %s to complete purchase", game.getTitle()));
}
}
// Create a new order for the customer
Order order = new Order(currentDate, null, customer);
order = orderRepo.save(order);
// Reduce stock for each game and create GameCopy records
double totalPrice = 0;
GameCopy gameCopy;
for (int i = 0; i < cartItems.length; i++) {
game = cartItems[i].getKey().getGame();
game.setStock(game.getStock() - cartItems[i].getQuantity());
game = gameRepo.save(game);
double gamePrice = game.getPrice();
for (int j = 0; j < cartItems[i].getQuantity(); j++) {
gameCopy = new GameCopy(order, game);
gameCopy = gameCopyRepo.save(gameCopy);
totalPrice += gamePrice;
}
}
// Clear customer's cart and save the order
clearCart(customer);
totalPrice *= 1.1; // Add the 10% QST
totalPrice += 5; // Add $5 delivery fee
order.setTotalPrice(totalPrice);
order = orderRepo.save(order);
return order;
}