aa1588 / campusXchange

A Campus-Focused Marketplace Addressing UNT Student Needs
3 stars 0 forks source link

Implement logging for Wishlist, offer module backend #92

Closed aa1588 closed 6 days ago

aa1588 commented 2 weeks ago

Related to User Story #2 #3 #4

Moni1319 commented 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);
    }
}
Moni1319 commented 6 days ago
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);
    }
}
``
Moni1319 commented 6 days ago
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);
        }
    }
}
Moni1319 commented 6 days ago
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;
        }
    }
}
Moni1319 commented 6 days ago

@aa1588