3
respostas

Problemas com o metodo de atualizar

Estudando fiz um mini projeto onde simulo a criação de uma nota fiscal. O crud em si já esta pronto porém estou com problemas na atualização da nota. Acontece que possuo uma classe itens que contém meus produtos, valor total, quantidade, etc e a classe nota que armazena o numero da nota e o seu valor total. Esta assim:

Itens:

public class Itens {

    @Id
    @JsonProperty("id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_produto")
    private Produto produto;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JsonIgnoreProperties("itens")
    private Nota nota;
    private Integer ordenacao;
    private BigDecimal quantidade;
    private BigDecimal valor_total;

Nota:

public class Nota {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "id_cliente")
    private Cliente cliente;

    @JsonManagedReference
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "nota", cascade = CascadeType.ALL)
    @JsonIgnoreProperties("nota")
    private List<Itens> itens;

    private Integer numero;
    private Date data;
    private BigDecimal valor_total;

O meu problema acontece no momento da atualização da nota. Consigo atualizar os itens com seu valor total, porém o valor total da nota não é atualizado. O que poderia estar errado? Segue meu método salvar do meu service:

 public void atualizar(NotaDTO dto) {
        Nota nota = repository.getReferenceById(dto.getId());
        List<Itens> list = itensRepository.findAllByIdItens(nota);
        BigDecimal somaTotal = BigDecimal.ZERO;

        if (dto.getCliente() != null && dto.getCliente().getId() != null) {
            Cliente cliente = clienteRepository.getReferenceById(dto.getCliente().getId());
            nota.setCliente(cliente);
        }

        int ordenacao = 1;

        for (Itens item : list) { //Percorrendo a lista de itens que já esta salva no banco de dados
            if (!dto.getItens().contains(itensRepository.getReferenceById(item.getId()))) {
                itensRepository.deleteById(item.getId());
            }
            for (Itens itemDTO : dto.getItens()) { //Percorrendo a lista do dto que estou recebendo
                if (itemDTO.getId() == null) {
                    item.setOrdenacao(ordenacao++);
                    itemDTO.setOrdenacao(ordenacao++);

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());
                    itemDTO.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));

                    item.setNota(nota);

                    break;
                }
                if (item.getId() == itemDTO.getId()) {
                    item.setQuantidade(itemDTO.getQuantidade());

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());

                    break;
                }
            }
        }

        nota.setValor_total(somaTotal);
        nota.atualizar(dto);
    }

Na minha classe nota da entidade esta assim:

public void atualizar(NotaDTO dto) {
        if (dto.getData() != null) {
            this.data = dto.getData();
       }

       if (dto.getValor_total() != null) {
            this.valor_total = dto.getValor_total();
       }

        if (dto.getItens() != null) {
            for (Itens itemDTO : dto.getItens()) {
                if (itemDTO.getId() == null) {
                    // Criar e adicionar novo item à lista
                    Itens novoItem = new Itens();
                    novoItem.setOrdenacao(itemDTO.getOrdenacao());
                    novoItem.setProduto(itemDTO.getProduto());
                    novoItem.setQuantidade(itemDTO.getQuantidade());
                    novoItem.setValor_total(itemDTO.getValor_total());
                    novoItem.setNota(this);
                    this.itens.add(novoItem);
                } else {
                    // Atualizar item existente
                    for (Itens item : this.itens) {
                        if (item.getId().equals(itemDTO.getId())) {
                            item.setQuantidade(itemDTO.getQuantidade());
                            break;
                        }
                    }
                }
            }
        }
    }
3 respostas

Oi Natali!

Acho que encontrei o seu problema... Vamo dar olhada nesse código aqui:

 public void atualizar(NotaDTO dto) {
        Nota nota = repository.getReferenceById(dto.getId());
        List<Itens> list = itensRepository.findAllByIdItens(nota);
        BigDecimal somaTotal = BigDecimal.ZERO;

        if (dto.getCliente() != null && dto.getCliente().getId() != null) {
            Cliente cliente = clienteRepository.getReferenceById(dto.getCliente().getId());
            nota.setCliente(cliente);
        }

        int ordenacao = 1;

        for (Itens item : list) { //Percorrendo a lista de itens que já esta salva no banco de dados
            if (!dto.getItens().contains(itensRepository.getReferenceById(item.getId()))) {
                itensRepository.deleteById(item.getId());
            }
            for (Itens itemDTO : dto.getItens()) { //Percorrendo a lista do dto que estou recebendo
                if (itemDTO.getId() == null) {
                    item.setOrdenacao(ordenacao++);
                    itemDTO.setOrdenacao(ordenacao++);

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());
                    itemDTO.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));

                    item.setNota(nota);

                    break;
                }
                if (item.getId() == itemDTO.getId()) {
                    item.setQuantidade(itemDTO.getQuantidade());

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());

                    break;
                }
            }
        }

        nota.setValor_total(somaTotal);
        nota.atualizar(dto);
    }

No final você executa o nota.setValortotal, o que está ok, esse método atualiza o atributo valor_total da NF usando o valor final da variável somaTotal. O problema é que quando você executa nota.atualizar(dto) você também altera o valor do atributo valor_total de novo, só que dessa vez, você pega o valor total que está no DTO, que é um valor desatualizado, era o valor original antes de toda a lógica que foi usada para chegar no que há na variável somaTotal. Veja só:

public void atualizar(NotaDTO dto) {
        if (dto.getData() != null) {
            this.data = dto.getData();
       }


//O erro está bem aqui
       if (dto.getValor_total() != null) {
            this.valor_total = dto.getValor_total();
       }

//lógica ocultada

Então é isso, primeiro você atualizou o valor_total com um método setter usando um valor correto, mas logo após você atualizou o valor_total de novo com o método atualizar usando um valor antigo.

No fim, esse método atualizar , por sempre alterar o valor_total está te induzindo ao erro. Existem diferentes formas de resolver isso, mas se você só inverter a ordem de chamado do método setValor_total e o atualizar já vai resolver seu problema. Se isso tiver te ajudado, marca aqui como a solução

Olá, Natali!

Pelo código que você compartilhou, parece que o problema está na atualização do valor total da nota. Verifiquei que você está calculando a soma dos valores totais dos itens corretamente, mas não está atribuindo esse valor à nota.

No método atualizar da classe Nota, você está verificando se o valor total do DTO não é nulo e, caso não seja, está atribuindo esse valor à nota. No entanto, parece que o valor total não está sendo atualizado corretamente.

Uma possível solução seria adicionar um log para verificar se o valor total está sendo corretamente calculado e se está sendo atribuído à nota. Além disso, verifique se o DTO está sendo corretamente preenchido com os valores atualizados antes de chamar o método atualizar da nota.

Se mesmo assim o problema persistir, sugiro verificar se há algum outro trecho de código que está alterando o valor total da nota após a chamada do método atualizar.

Bons estudos!

Consegui resolver o problema do valor, mas agora a minha lista de itens que não é atualizada quando eu removo algum da lista. Além diso, quando adiciono um novo item na lista também não adiciona a sua ordenação. Atualmente meu código esta assim: metodo atualizar service:

public void atualizar(NotaDTO dto) {
        Nota nota = repository.getReferenceById(dto.getId());
        List<Itens> list = itensRepository.findAllByIdItens(nota);
        BigDecimal somaTotal = BigDecimal.ZERO;
        BigDecimal somaTotalDTO = BigDecimal.ZERO;

        for (Itens item : list) { //Percorrendo a lista de itens que já esta salva no banco de dados
            if (!dto.getItens().contains(itensRepository.getReferenceById(item.getId()))) {
                itensRepository.deleteById(item.getId());
            }
            for (Itens itemDTO : dto.getItens()) { //Percorrendo a lista do dto que estou recebendo
                if (itemDTO.getId() == null) {
                    int ordenacao = itensRepository.findByUltimaOrdencao(nota);
                    item.setOrdenacao(ordenacao++);
                    itemDTO.setOrdenacao(ordenacao++);

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());
                    itemDTO.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));

                    item.setNota(nota);

                    break;
                }
                if (item.getId() == itemDTO.getId()) {
                    item.setQuantidade(itemDTO.getQuantidade());

                    Long valorUnitario = produtoRepository.findByValorUnitarioProduto(item.getProduto().getId());

                    item.setValor_total(item.getQuantidade().multiply(BigDecimal.valueOf(valorUnitario)));
                    somaTotal = somaTotal.add(item.getValor_total());
                    somaTotalDTO = somaTotalDTO.add(item.getValor_total());

                    break;
                }
            }
        }

        dto.setValor_total(somaTotalDTO);
        nota.setValor_total(somaTotal);
        nota.atualizar(dto);
    }

metodo atualizar na entidade:

public void atualizar(NotaDTO dto) {
        if (dto.getCliente() != null) {
            this.cliente = new Cliente(new ClienteDTO());
        }
        if (dto.getItens() != null) {
            for (Itens itemDTO : dto.getItens()) {
                if (itemDTO.getId() == null) {
                    // Criar e adicionar novo item à lista
                    Itens novoItem = new Itens();
                    novoItem.setOrdenacao(itemDTO.getOrdenacao());
                    novoItem.setProduto(itemDTO.getProduto());
                    novoItem.setQuantidade(itemDTO.getQuantidade());
                    novoItem.setValor_total(itemDTO.getValor_total());
                    novoItem.setNota(this);
                    this.itens.add(novoItem);
                } else {
                    // Atualizar item existente
                    for (Itens item : this.itens) {
                        if (item.getId().equals(itemDTO.getId())) {
                            item.setQuantidade(itemDTO.getQuantidade());
                            break;
                        }
                    }
                }
            }
        }
        if (dto.getData() != null) {
            this.data = dto.getData();
        }
        if (dto.getValor_total() != null) {
            this.valor_total = dto.getValor_total();
        }
    }

minha entidade nota esta com esta referência de itens:

@JsonManagedReference
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "nota", cascade = CascadeType.ALL)
    @JsonIgnoreProperties("nota")
    private List<Itens> itens;

minha entidade itens com a referência da nota:

@JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JsonIgnoreProperties("itens")
    private Nota nota;