Closed aa1588 closed 6 days ago
package com.unt.campusxchange.offers.controller;
import com.unt.campusxchange.offers.dto.OfferDTO;
import com.unt.campusxchange.offers.service.OfferService;
import java.security.Principal;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/offers")
@RequiredArgsConstructor
public class OfferController {
private final OfferService offerService;
@PostMapping("/create/{itemId}")
public ResponseEntity<OfferDTO> createOffer(
@PathVariable Integer itemId, @RequestBody OfferDTO offerDTO, Principal principal) {
try {
String currentUsername = principal.getName(); // username == email
logger.info("Creating offer for item ID: {} by user: {}", itemId, currentUsername);
OfferDTO offer = offerService.createOffer(currentUsername, itemId, offerDTO);
logger.info("Offer created successfully for item ID: {} by user: {}", itemId, currentUsername);
return new ResponseEntity<>(offer, HttpStatus.CREATED);
} catch (Exception e) {
logger.error(
"Error creating offer for item ID: {} by user: {}, error: {}",
itemId,
principal.getName(),
e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@GetMapping("/item/{itemId}")
public ResponseEntity<List<OfferDTO>> getOffersForItem(@PathVariable Integer itemId, Principal principal) {
String currentUsername = principal.getName(); // username == email
logger.info("Fetching offers for item ID: {} by user: {}", itemId, currentUsername);
List<OfferDTO> offers = offerService.listOffersForItem(currentUsername, itemId);
logger.info("Returning {} offers for item ID: {}", offers.size(), itemId);
return ResponseEntity.ok(offers);
}
@PutMapping("/{offerId}/accept")
public ResponseEntity<OfferDTO> acceptOffer(@PathVariable Integer offerId, Principal principal) {
String email = principal.getName(); // Get the email from Principal
logger.info("User {} is accepting offer ID: {}", email, offerId);
System.out.println("email: " + email);
OfferDTO updatedOffer = offerService.acceptOffer(offerId, email);
logger.info("Offer ID: {} accepted by user: {}", offerId, email);
return ResponseEntity.ok(updatedOffer);
}
@PutMapping("/{offerId}/decline")
public ResponseEntity<OfferDTO> declineOffer(@PathVariable Integer offerId, Principal principal) {
String email = principal.getName(); // Get the email from Principal
logger.info("User {} is declining offer ID: {}", email, offerId);
OfferDTO updatedOffer = offerService.declineOffer(offerId, email);
logger.info("Offer ID: {} declined by user: {}", offerId, email);
return ResponseEntity.ok(updatedOffer);
}
}
package com.unt.campusxchange.offers.service;
import com.unt.campusxchange.items.entity.Item;
import com.unt.campusxchange.items.exception.ItemNotFoundException;
import com.unt.campusxchange.items.repo.ItemRepository;
import com.unt.campusxchange.offers.dto.ItemDTO;
import com.unt.campusxchange.offers.dto.OfferDTO;
import com.unt.campusxchange.offers.dto.OfferItemDTO;
import com.unt.campusxchange.offers.dto.UserDTO;
import com.unt.campusxchange.offers.entity.Offer;
import com.unt.campusxchange.offers.entity.OfferItem;
import com.unt.campusxchange.offers.entity.OfferStatus;
import com.unt.campusxchange.offers.exception.OfferNotFoundException;
import com.unt.campusxchange.offers.repo.OfferRepository;
import com.unt.campusxchange.users.entity.User;
import com.unt.campusxchange.users.exception.UserNotFoundException;
import com.unt.campusxchange.users.repo.UserRepository;
import jakarta.transaction.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
@Transactional
@RequiredArgsConstructor
public class OfferService {
private static final Logger logger = LoggerFactory.getLogger(OfferService.class);
private final OfferRepository offerRepository;
private final ItemRepository itemRepository;
private final UserRepository userRepository;
public OfferDTO createOffer(String email, Integer itemId, OfferDTO offerDTO) {
logger.info("Creating offer for item ID: {} by user: {}", itemId, email);
try {
User user =
userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("User not found"));
Item mainItem =
itemRepository.findById(itemId).orElseThrow(() -> new ItemNotFoundException("Item not found"));
Offer offer = new Offer();
offer.setAmount(offerDTO.amount());
offer.setOfferedBy(user);
offer.setItem(mainItem);
offer.setStatus(OfferStatus.PENDING);
// Only map offerItems if they are provided in the request
List<OfferItem> offerItems = offerDTO.offerItems() != null
? offerDTO.offerItems().stream()
.map(offerItemDTO -> {
Item item = itemRepository
.findById(offerItemDTO.itemId())
.orElseThrow(() -> new ItemNotFoundException("Item not found"));
OfferItem offerItem = new OfferItem();
offerItem.setOffer(offer);
offerItem.setItem(item);
offerItem.setQuantity(offerItemDTO.quantity());
return offerItem;
})
.collect(Collectors.toList())
: Collections.emptyList();
offer.setOfferItems(offerItems);
Offer savedOffer = offerRepository.save(offer);
logger.info("Offer created successfully for item ID: {} by user: {}", itemId, email);
return toOfferDTO(savedOffer);
} catch (Exception e) {
logger.error("Error creating offer for item ID: {} by user: {} - {}", itemId, email, e.getMessage());
throw e;
}
}
private OfferDTO toOfferDTO(Offer offer) {
List<OfferItemDTO> offerItemDTOs = offer.getOfferItems() != null
? offer.getOfferItems().stream()
.map(offerItem -> new OfferItemDTO(offerItem.getItem().getId(), offerItem.getQuantity()))
.collect(Collectors.toList())
: Collections.emptyList();
UserDTO userDTO = new UserDTO(
offer.getOfferedBy().getId(),
offer.getOfferedBy().getFirstname(),
offer.getOfferedBy().getLastname(),
offer.getOfferedBy().getEmail(),
offer.getOfferedBy().getPhone());
ItemDTO itemDTO = new ItemDTO(
offer.getItem().getId(),
offer.getItem().getTitle(),
offer.getItem().getQuantity(),
offer.getItem().getDescription(),
offer.getItem().getPrice(),
offer.getItem().getCategory().toString(),
offer.getItem().getImageUrls());
return new OfferDTO(
offer.getId(),
offer.getAmount(),
userDTO,
itemDTO,
offer.getStatus(),
offerItemDTOs,
offer.getCreatedAt());
}
public List<OfferDTO> listOffersForItem(String email, Integer itemId) {
logger.info("Listing offers for item ID: {} by user: {}", itemId, email);
User user = userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("User not found"));
// Check if the item exists and if the user is the owner
Item item = itemRepository.findById(itemId).orElseThrow(() -> new ItemNotFoundException("Item not found"));
if (!item.getUser().equals(user)) {
logger.warn("Security exception: User {} is not the owner of item ID: {}", email, itemId);
throw new SecurityException("User is not the owner of this item.");
}
// Fetch all offers for the item
List<Offer> offers = offerRepository.findByItem(item);
logger.info("Found {} offers for item ID: {}", offers.size(), itemId);
// Map offers to DTOs
return offers.stream().map(this::toOfferDTO).collect(Collectors.toList());
}
public OfferDTO acceptOffer(Integer offerId, String email) {
logger.info("User {} is accepting offer ID: {}", email, offerId);
Offer offer =
offerRepository.findById(offerId).orElseThrow(() -> new OfferNotFoundException("Offer not found"));
// Check if the user is the owner of the item
User itemOwner = offer.getItem().getUser(); // Assuming you have a getOwner() method in Item entity
if (!itemOwner.getEmail().equals(email)) {
logger.warn("User {} is not the owner of the item in offer ID: {}", email, offerId);
throw new UserNotFoundException("You are not the owner of this item.");
}
offer.setStatus(OfferStatus.ACCEPTED);
Offer savedOffer = offerRepository.save(offer);
logger.info("Offer ID: {} accepted by user: {}", offerId, email);
return toOfferDTO(savedOffer);
}
public OfferDTO declineOffer(Integer offerId, String email) {
logger.info("User {} is declining offer ID: {}", email, offerId);
Offer offer =
offerRepository.findById(offerId).orElseThrow(() -> new OfferNotFoundException("Offer not found"));
// Check if the user is the owner of the item
User itemOwner = offer.getItem().getUser(); // Assuming you have a getOwner() method in Item entity
if (!itemOwner.getEmail().equals(email)) {
logger.warn("User {} is not the owner of the item in offer ID: {}", email, offerId);
throw new UserNotFoundException("You are not the owner of this item.");
}
offer.setStatus(OfferStatus.DECLINED);
Offer savedOffer = offerRepository.save(offer);
logger.info("Offer ID: {} declined by user: {}", offerId, email);
return toOfferDTO(savedOffer);
}
}
``
package com.unt.campusxchange.wishlist.controller;
import com.unt.campusxchange.items.dto.CreateItemResponse;
import com.unt.campusxchange.wishlist.service.WishlistService;
import java.security.Principal;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/wishlists")
@RequiredArgsConstructor
public class WishlistController {
private static final Logger logger = LoggerFactory.getLogger(WishlistController.class);
private final WishlistService wishlistService;
@PostMapping("/add/{itemId}")
public ResponseEntity<String> addItemToWishList(@PathVariable Integer itemId, Principal principal) {
String currentUsername = principal.getName();
logger.info("Adding item with ID: {} to wishlist for user: {}", itemId, currentUsername);
try {
wishlistService.addItemToWishlist(currentUsername, itemId);
logger.info("Item with ID: {} successfully added to wishlist for user: {}", itemId, currentUsername);
return new ResponseEntity<>("Item added to wishlist.", HttpStatus.CREATED);
} catch (Exception e) {
logger.error(
"Failed to add item with ID: {} to wishlist for user: {} - {}",
itemId,
currentUsername,
e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@GetMapping("items/me")
public ResponseEntity<List<CreateItemResponse>> getUserWishlist(Principal principal) {
String currentUsername = principal.getName();
logger.info("Retrieving wishlist for user: {}", currentUsername);
try {
List<CreateItemResponse> myWishlist = wishlistService.getMyWishlist(currentUsername);
logger.info("Wishlist retrieved successfully for user: {}", currentUsername);
return new ResponseEntity<>(myWishlist, HttpStatus.OK);
} catch (Exception e) {
logger.error("Failed to retrieve wishlist for user: {} - {}", currentUsername, e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@DeleteMapping("/item/{itemId}")
public ResponseEntity<String> deleteWishlistItem(@PathVariable Integer itemId, Principal principal) {
String currentUsername = principal.getName(); // username == email
logger.info("Deleting item with ID: {} from wishlist for user: {}", itemId, currentUsername);
try {
wishlistService.deleteWishlistItem(currentUsername, itemId);
logger.info("Item with ID: {} successfully removed from wishlist for user: {}", itemId, currentUsername);
return new ResponseEntity<>("Item removed from the wishlist.", HttpStatus.OK);
} catch (Exception e) {
logger.error(
"Failed to delete item with ID: {} from wishlist for user: {} - {}",
itemId,
currentUsername,
e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
}
package com.unt.campusxchange.wishlist.service;
import com.unt.campusxchange.items.dto.CreateItemResponse;
import com.unt.campusxchange.items.entity.Item;
import com.unt.campusxchange.items.exception.ItemNotFoundException;
import com.unt.campusxchange.items.repo.ItemRepository;
import com.unt.campusxchange.users.entity.User;
import com.unt.campusxchange.users.exception.UserNotFoundException;
import com.unt.campusxchange.users.repo.UserRepository;
import com.unt.campusxchange.wishlist.entity.WishlistItem;
import com.unt.campusxchange.wishlist.exception.WishlistItemNotFoundException;
import com.unt.campusxchange.wishlist.repo.WishlistRepository;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
@RequiredArgsConstructor
public class WishlistService {
private static final Logger logger = LoggerFactory.getLogger(WishlistService.class);
private final WishlistRepository wishlistRepository;
private final ItemRepository itemRepository;
private final UserRepository userRepository;
public void addItemToWishlist(String email, Integer id) {
logger.info("Adding item with ID: {} to wishlist for user with email: {}", id, email);
User user = userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("User not found"));
Item item = itemRepository.findById(id).orElseThrow(() -> new ItemNotFoundException("Item not found"));
WishlistItem wishlistItem = new WishlistItem();
wishlistItem.setUser(user);
wishlistItem.setItem(item);
wishlistRepository.save(wishlistItem);
logger.info("Item with ID: {} successfully added to wishlist for user with email: {}", id, email);
} catch (Exception e) {
logger.error("Failed to add item with ID: {} to wishlist for user with email: {} - {}", id, email, e.getMessage());
throw e;
}
}
public List<CreateItemResponse> getMyWishlist(String email) {
logger.info("Fetching wishlist for user with email: {}", email);
try {
User user = userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("User not found"));
List<CreateItemResponse> wishlist = wishlistRepository.findByUserId(user.getId()).stream()
.map(wishlistItem -> {
.map(wishlistItem -> {
Item item = wishlistItem.getItem();
return new CreateItemResponse(
item.getId(),
item.getTitle(),
item.getQuantity(),
item.getDescription(),
item.getPrice(),
item.getCategory().name(),
item.getUser().getId(),
item.getImageUrls(),
item.getCreatedAt(),
item.getUpdatedAt());
})
.collect(Collectors.toList());
logger.info("Wishlist fetched successfully for user with email: {}", email);
return wishlist;
} catch (Exception e) {
logger.error("Failed to fetch wishlist for user with email: {} - {}", email, e.getMessage());
throw e;
}
public void deleteWishlistItem(String email, Integer itemId) {
logger.info("Removing item with ID: {} from wishlist for user with email: {}", itemId, email);
try {
User user = userRepository.findByEmail(email).orElseThrow(() -> new UserNotFoundException("User not found"));
Item item = itemRepository.findById(itemId).orElseThrow(() -> new ItemNotFoundException("Item not found"));
WishlistItem wishlistItem = wishlistRepository
.findByUserIdAndItemId(user.getId(), item.getId())
.orElseThrow(() -> new WishlistItemNotFoundException("Item not found in wishlist"));
wishlistRepository.delete(wishlistItem);
logger.info("Item with ID: {} successfully removed from wishlist for user with email: {}", itemId, email);
} catch (Exception e) {
logger.error("Failed to remove item with ID: {} from wishlist for user with email: {} - {}", itemId, email, e.getMessage());
throw e;
}
}
}
@aa1588
Related to User Story #2 #3 #4