Skip to content

Commit

Permalink
Merge pull request #9 from vanderleik/PPI-9-Criar-ProductService
Browse files Browse the repository at this point in the history
Ppi 9 criar product service
  • Loading branch information
vanderleik authored Jul 10, 2024
2 parents 1c40608 + 1c14744 commit 0b33a5f
Show file tree
Hide file tree
Showing 10 changed files with 467 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.produtopedidoitens.api.adapters.web.requests;

import lombok.Builder;

@Builder
public record ProductRequest(
String productName,
String price,
String type,
String active
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.produtopedidoitens.api.adapters.web.responses;

import com.produtopedidoitens.api.application.domain.enums.EnumProductType;
import lombok.Builder;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

@Builder
public record ProductResponse(
UUID id,
String productName,
BigDecimal price,
EnumProductType type,
Boolean active,
LocalDateTime dthreg,
LocalDateTime dthalt,
Long version
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.produtopedidoitens.api.application.exceptions;

public class BadRequestException extends RuntimeException {

public BadRequestException(String message) {
super(message);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.produtopedidoitens.api.application.exceptions;

public class ProductNotFoundException extends RuntimeException {

public ProductNotFoundException(String message) {
super(message);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.produtopedidoitens.api.application.mapper;

import com.produtopedidoitens.api.application.domain.enums.EnumCode;
import lombok.experimental.UtilityClass;

@UtilityClass
public class EnumConverter {

public static <T extends Enum<T> & EnumCode> T fromString(String value, Class<T> enumType) {
for (T enumValue : enumType.getEnumConstants()) {
if (enumValue.getCode().equals(value)) {
return enumValue;
}
}
throw new IllegalArgumentException("No enum constant " + enumType.getSimpleName() + " with code " + value);
}

public static <T extends Enum<T>> String toString(T enumValue) {
return ((EnumCode) enumValue).getCode();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.produtopedidoitens.api.application.mapper;

import com.produtopedidoitens.api.adapters.web.requests.ProductRequest;
import com.produtopedidoitens.api.adapters.web.responses.ProductResponse;
import com.produtopedidoitens.api.application.domain.entities.ProductEntity;
import com.produtopedidoitens.api.application.domain.enums.EnumProductType;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Component
public class ProductConverter {


public ProductEntity toEntity(ProductRequest productRequest) {
return ProductEntity.builder()
.productName(productRequest.productName())
.price(new BigDecimal(productRequest.price()))
.type(EnumConverter.fromString(productRequest.type(), EnumProductType.class))
.active(Boolean.parseBoolean(productRequest.active()))
.build();
}

public ProductResponse toResponse(ProductEntity entitySaved) {
return ProductResponse.builder()
.id(entitySaved.getId())
.productName(entitySaved.getProductName())
.price(entitySaved.getPrice())
.type(entitySaved.getType())
.active(entitySaved.getActive())
.dthreg(entitySaved.getDthreg())
.dthalt(entitySaved.getDthalt())
.version(entitySaved.getVersion())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.produtopedidoitens.api.application.port;

import com.produtopedidoitens.api.adapters.web.requests.ProductRequest;
import com.produtopedidoitens.api.adapters.web.responses.ProductResponse;

import java.util.List;
import java.util.UUID;

public interface ProductInputPort {

ProductResponse create(ProductRequest productRequest);
List<ProductResponse> list();
ProductResponse read(UUID id);
ProductResponse update(UUID id, ProductRequest productRequest);
void delete(UUID id);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.produtopedidoitens.api.application.services;

import com.produtopedidoitens.api.adapters.persistence.repositories.ProductRepository;
import com.produtopedidoitens.api.adapters.web.requests.ProductRequest;
import com.produtopedidoitens.api.adapters.web.responses.ProductResponse;
import com.produtopedidoitens.api.application.domain.entities.ProductEntity;
import com.produtopedidoitens.api.application.domain.enums.EnumProductType;
import com.produtopedidoitens.api.application.exceptions.BadRequestException;
import com.produtopedidoitens.api.application.exceptions.ProductNotFoundException;
import com.produtopedidoitens.api.application.mapper.EnumConverter;
import com.produtopedidoitens.api.application.mapper.ProductConverter;
import com.produtopedidoitens.api.application.port.ProductInputPort;
import com.produtopedidoitens.api.utils.MessagesConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

@Slf4j
@RequiredArgsConstructor
@Service
public class ProductServiceImpl implements ProductInputPort {

private final ProductRepository productRepository;
private final ProductConverter productConverter;

@Transactional(rollbackFor = Exception.class)
@Override
public ProductResponse create(ProductRequest productRequest) {
log.info("create:: Recebendo productRequest: {}", productRequest);
try {
ProductEntity entitySaved = productRepository.save(getEntity(productRequest));
ProductResponse response = productConverter.toResponse(entitySaved);
log.info("create:: Salvando produto/serviço: {}", response);
return response;
} catch (Exception e) {
log.error("create:: Ocorreu um erro ao salvar o produto/serviço");
throw new BadRequestException(MessagesConstants.ERROR_SAVE_PRODUCT);
}
}

@Override
public List<ProductResponse> list() {
log.info("list:: Listando produtos/serviços");
List<ProductEntity> list = getProductEntities();
log.info("list:: Produtos/serviços listados com sucesso: {}", list);
return list.stream().map(productConverter::toResponse).toList();
}

@Override
public ProductResponse read(UUID id) {
log.info("read:: Buscando produto/serviço pelo id: {}", id);
ProductEntity entity = getProductEntity(id);
log.info("read:: Produto/serviço encontrado: {}", entity);
return productConverter.toResponse(entity);
}

@Transactional(rollbackFor = Exception.class)
@Override
public ProductResponse update(UUID id, ProductRequest productRequest) {
log.info("update:: Recebendo requisição para atualizar produto/serviço: {}", productRequest);
ProductEntity entity = getProductEntity(id);
updateEntity(productRequest, entity);
try {
ProductEntity entitySaved = productRepository.save(entity);
ProductResponse response = productConverter.toResponse(entitySaved);
log.info("update:: Atualizando produto/serviço na base: {}", response);
return response;
} catch (Exception e) {
log.error("update:: Ocorreu um erro ao atualizar o produto/serviço");
throw new BadRequestException(MessagesConstants.ERROR_UPDATE_PRODUCT);
}
}

@Transactional(rollbackFor = Exception.class)
@Override
public void delete(UUID id) {
log.info("delete:: Recebendo requisição para deletar produto/serviço pelo id: {}", id);
ProductEntity entity = getProductEntity(id);
try {
productRepository.delete(entity);
log.info("delete:: Deletando produto/serviço da base: {}", entity);
} catch (Exception e) {
log.error("delete:: Ocorreu um erro ao deletar o produto/serviço");
throw new BadRequestException(MessagesConstants.ERROR_DELETE_PRODUCT);
}
}

private static void updateEntity(ProductRequest productRequest, ProductEntity entity) {
entity.setProductName(productRequest.productName() == null ? entity.getProductName() : productRequest.productName());
entity.setPrice(productRequest.price() == null ? entity.getPrice() : new BigDecimal(productRequest.price()));
entity.setType(productRequest.type() == null ? entity.getType() : EnumConverter.fromString(productRequest.type(), EnumProductType.class));
entity.setActive(productRequest.active() == null ? entity.getActive() : Boolean.parseBoolean(productRequest.active()));
}

private ProductEntity getProductEntity(UUID id) {
return productRepository.findById(id)
.orElseThrow(() -> {
log.error("read:: Ocorreu um erro ao buscar o produto/serviço pelo id: {}", MessagesConstants.ERROR_PRODUCT_NOT_FOUND);
throw new ProductNotFoundException(MessagesConstants.ERROR_PRODUCT_NOT_FOUND);
});
}

private ProductEntity getEntity(ProductRequest productRequest) {
return productConverter.toEntity(productRequest);
}

private List<ProductEntity> getProductEntities() {
List<ProductEntity> list = productRepository.findAll();
if (list.isEmpty()) {
log.error("list:: Ocorreu um erro ao listar os produtos/serviços: {}", MessagesConstants.ERROR_PRODUCT_NOT_FOUND);
throw new ProductNotFoundException(MessagesConstants.ERROR_PRODUCT_NOT_FOUND);
}
return list;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
public class MessagesConstants {

//PRODUCT
public static final String PRODUCT_NAME_NOT_BLANK = "O nome do produto não pode ser vazio";
public static final String PRODUCT_PRICE_NOT_NULL = "O preço do produto não pode ser nulo";
public static final String PRODUCT_ACTIVE_NOT_NULL = "O status do produto não pode ser nulo";
public static final String PRODUCT_PRICE_POSITIVE = "O preço do produto deve ser um valor positivo";
public static final String PRODUCT_TYPE_NOT_NULL = "O tipo do produto não pode ser nulo";
public static final String PRODUCT_NAME_NOT_BLANK = "O nome do produto/serviço não pode ser vazio";
public static final String PRODUCT_PRICE_NOT_NULL = "O preço do produto/serviço não pode ser nulo";
public static final String PRODUCT_ACTIVE_NOT_NULL = "O status do produto/serviço não pode ser nulo";
public static final String PRODUCT_PRICE_POSITIVE = "O preço do produto/serviço deve ser um valor positivo";
public static final String PRODUCT_TYPE_NOT_NULL = "O tipo do produto/serviço não pode ser nulo";
public static final String ERROR_SAVE_PRODUCT = "Erro ao salvar produto/serviço";
public static final String ERROR_PRODUCT_NOT_FOUND = "Nenhum produto/serviço encontrado";
public static final String ERROR_UPDATE_PRODUCT = "Erro ao atualizar produto/serviço";
public static final String ERROR_DELETE_PRODUCT = "Erro ao deletar produto/serviço";

//ORDER
public static final String ORDER_DATE_NOT_NULL = "A data do pedido não pode ser nula";
Expand Down
Loading

0 comments on commit 0b33a5f

Please sign in to comment.