Skip to content

Commit

Permalink
implement return product logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatIgnatov committed Apr 25, 2024
1 parent 5f83ec7 commit bee652b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@
import jakarta.validation.Valid;
import jewellery.inventory.dto.request.SaleRequestDto;
import jewellery.inventory.dto.response.OrganizationSaleResponseDto;
import jewellery.inventory.service.SaleFromOrganizationService;
import jewellery.inventory.dto.response.ProductReturnResponseDto;
import jewellery.inventory.service.OrganizationSaleService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/organizations")
@RequiredArgsConstructor
public class OrganizationSaleController {

private final SaleFromOrganizationService saleFromOrganizationService;
private final OrganizationSaleService organizationSaleService;

@Operation(summary = "Create sale from organization to user")
@ResponseStatus(HttpStatus.OK)
@PostMapping("/sales")
public OrganizationSaleResponseDto createSale(@Valid @RequestBody SaleRequestDto saleRequestDto) {
return saleFromOrganizationService.createSale(saleRequestDto);
return organizationSaleService.createSale(saleRequestDto);
}

@Operation(summary = "Return of a sold product from user to organization")
@ResponseStatus(HttpStatus.OK)
@PutMapping("/return-product/{productId}")
public ProductReturnResponseDto returnProduct(@PathVariable("productId") UUID productId) {
return organizationSaleService.returnProduct(productId);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package jewellery.inventory.mapper;

import java.util.List;
import jewellery.inventory.dto.response.ProductResponseDto;
import jewellery.inventory.dto.response.ProductsInOrganizationResponseDto;
import jewellery.inventory.model.Organization;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class ProductInOrganizationMapper {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/jewellery/inventory/model/EventType.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ public enum EventType {
ORGANIZATION_PRODUCT_DISASSEMBLY,
ORGANIZATION_PRODUCT_TRANSFER,
ORGANIZATION_RESOURCE_TRANSFER,
ORGANIZATION_CREATE_SALE
ORGANIZATION_CREATE_SALE,
ORGANIZATION_SALE_RETURN_PRODUCT
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@
import jewellery.inventory.dto.request.PurchasedResourceQuantityRequestDto;
import jewellery.inventory.dto.request.SaleRequestDto;
import jewellery.inventory.dto.response.OrganizationSaleResponseDto;
import jewellery.inventory.dto.response.ProductReturnResponseDto;
import jewellery.inventory.exception.organization.OrganizationNotOwnerException;
import jewellery.inventory.mapper.SaleMapper;
import jewellery.inventory.model.*;
import jewellery.inventory.repository.SaleRepository;
import jewellery.inventory.service.security.AuthService;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class SaleFromOrganizationService {
public class OrganizationSaleService {

private static final Logger logger = LogManager.getLogger(SaleFromOrganizationService.class);
private static final Logger logger = LogManager.getLogger(OrganizationSaleService.class);

private final SaleService saleService;
private final SaleMapper saleMapper;
private final OrganizationService organizationService;
private final UserService userService;
private final ResourceInOrganizationService resourceInOrganizationService;
private final SaleRepository saleRepository;
private final AuthService authService;
private final ProductService productService;

@LogCreateEvent(eventType = EventType.ORGANIZATION_CREATE_SALE)
@Transactional
Expand Down Expand Up @@ -66,6 +66,71 @@ public OrganizationSaleResponseDto createSale(SaleRequestDto saleRequestDto) {
return saleMapper.mamToOrganizationSaleResponseDto(createdSale);
}

@LogCreateEvent(eventType = EventType.ORGANIZATION_SALE_RETURN_PRODUCT)
@Transactional
public ProductReturnResponseDto returnProduct(UUID productId) {

Product productToReturn = productService.getProduct(productId);

saleService.throwExceptionIfProductIsPartOfAnotherProduct(productToReturn);
saleService.throwExceptionIfProductNotSold(productToReturn);

Sale sale = saleService.getSale(productToReturn.getPartOfSale().getSale().getId());

organizationService.validateUserInOrganization(
organizationService.getOrganization(sale.getOrganizationSeller().getId()));
organizationService.validateCurrentUserPermission(
organizationService.getOrganization(sale.getOrganizationSeller().getId()),
OrganizationPermission.RETURN_PRODUCT);

sale.getProducts()
.removeIf(
productPriceDiscount -> productPriceDiscount.getProduct().getId().equals(productId));

updateProductsOrganizationOwner(productToReturn, sale.getOrganizationSeller(), sale);
saleService.deleteSaleIfProductsAndResourcesAreEmpty(sale);
logger.info("Product returned successfully. Product ID: {}", productId);
return saleService.validateSaleAfterReturnProduct(sale, productToReturn);
}

private void updateProductsOrganizationOwner(
Product product, Organization organization, Sale sale) {
updateProductsOrganizationOwnerRecursively(product, organization);

if (sale == null) {
product.setPartOfSale(null);
} else {
sale.getProducts()
.forEach(
productPriceDiscount -> {
if (productPriceDiscount.getProduct().equals(product)) {
product.setPartOfSale(productPriceDiscount);
}
});
}
logger.debug(
"Updated products organization owner and sale for product with ID: {}. New organizations owner with ID: {}, Sale with ID: {}",
product.getId(),
product.getOrganization().getId(),
product.getPartOfSale() != null ? product.getPartOfSale().getId() : null);
productService.saveProduct(product);
}

private void updateProductsOrganizationOwnerRecursively(
Product product, Organization organization) {
product.setOrganization(organization);
logger.debug(
"Updated organization owner for product with ID: {}. New organization owner with ID: {}",
product.getId(),
organization.getId());
if (product.getProductsContent() != null) {
List<Product> subProducts = product.getProductsContent();
for (Product subProduct : subProducts) {
updateProductsOrganizationOwnerRecursively(subProduct, organization);
}
}
}

private void removeQuantityFromResourcesInOrganization(SaleRequestDto saleRequestDto, Sale sale) {
for (PurchasedResourceInUser resource : sale.getResources()) {
resourceInOrganizationService.removeQuantityFromResource(
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/jewellery/inventory/service/SaleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private static void removeResourceFromSale(Sale sale, PurchasedResourceInUser re
.equals(resourceToReturn.getResource().getId()));
}

private Sale getSale(UUID saleId) {
public Sale getSale(UUID saleId) {
return saleRepository.findById(saleId).orElseThrow(() -> new SaleNotFoundException(saleId));
}

Expand All @@ -131,13 +131,13 @@ public void throwExceptionIfProductIsPartOfAnotherProduct(List<ProductPriceDisco
}
}

private void throwExceptionIfProductIsPartOfAnotherProduct(Product product) {
public void throwExceptionIfProductIsPartOfAnotherProduct(Product product) {
if (product.getContentOf() != null) {
throw new ProductIsContentException(product.getId());
}
}

private void throwExceptionIfProductNotSold(Product product) {
public void throwExceptionIfProductNotSold(Product product) {
if (product.getPartOfSale() == null) {
throw new ProductNotSoldException(product.getId());
}
Expand Down Expand Up @@ -178,7 +178,7 @@ public List<ProductPriceDiscount> getProductsFromSaleRequestDto(SaleRequestDto s
return new ArrayList<>();
}

private void deleteSaleIfProductsAndResourcesAreEmpty(Sale sale) {
public void deleteSaleIfProductsAndResourcesAreEmpty(Sale sale) {
if (sale.getProducts().isEmpty() && sale.getResources().isEmpty()) {
logger.info(
"Deleting sale with ID: {} since the both products list and resources list are empty.",
Expand All @@ -192,7 +192,7 @@ private void deleteSaleIfProductsAndResourcesAreEmpty(Sale sale) {
}
}

private ProductReturnResponseDto validateSaleAfterReturnProduct(
public ProductReturnResponseDto validateSaleAfterReturnProduct(
Sale sale, Product productToReturn) {
if (sale.getProducts().isEmpty() && sale.getResources().isEmpty()) {
return productService.getProductReturnResponseDto(null, productToReturn);
Expand Down

0 comments on commit bee652b

Please sign in to comment.