Ultimo problema para finalizar meu primeiro Sistema

Boa tarde a todos, há alguns meses comecei a desenvolver meu primeiro sistema web, sem nenhum conhecimento, com um frame pouco utilizado no Brasil, o Vaadin. Graças a ajuda de vários colegas aqui do fórum, hoje estou quase finalizando este projeto, aprendi muito com cada colega, e agradeço a cada um que ajudou.

Para finalizar este sistema, tenho um ultimo problema.

Esta é minha janela de Vendas:

na parte superior desta janela tenho os dados do cliente, então seleciono o nome do cliente para preencher os dados, ao selecionar o nome do cliente, os demais dados são preenchidos automaticamente:

restando apenas o campo forma de pagamento, que o usuario pode escolher antes de selecionar os produtos a serem vendidos…ou após, para efeitos de teste vamos selecionar agora no começo(o erro se da das duas maneiras)

Forma de pagamento Selecionada:

Agora adiciono os produtos, para isso clico em “+Item” :

os campos referentes aos produtos são adicionados…vou add 3 produtos

clico em salvar e a venda é salva na lista/grid

Até aqui ok, tudo certo…agora vamos ao problema

se eu fechar o navegador, ou der F5 acontece isso quando eu tento alterar ou visualizar(duplo clique) a venda:

erro/problema: Os produtos vendidos, são limpos / apagados

Não sei o que fiz de errado, creio que seja algo simples, mas como estou começando com programação, tudo pra mim é bem complicado. Alguém poderia me dar uma ajuda ou ideia para consertar estes problemas?

Seguem códigos:

Classe FormasDePagamento:

package br.com.fjsistemas.backend;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class FormasDePagamento {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	private String forma; 
	private String condicao;
	
}

Classe Venda:

package br.com.fjsistemas.backend;

import java.time.LocalDate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Venda {

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

	private LocalDate dataVenda = LocalDate.now();

	@ManyToOne
	private Cliente cliente;
	
	@ManyToOne
	private FormasDePagamento formasDepagamento;
	
	private String valorTotalVenda;
}

Classe VendaView(UI)

package br.com.fjsistemas.compraVenda;

import java.text.NumberFormat;
import java.text.ParseException;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.textfieldformatter.CustomStringBlockFormatter;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.PropertyId;
import com.vaadin.flow.data.renderer.LocalDateRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;

import br.com.fjsistemas.backend.Cliente;
import br.com.fjsistemas.backend.FormasDePagamento;
import br.com.fjsistemas.backend.Produto;
import br.com.fjsistemas.backend.Venda;
import br.com.fjsistemas.main.MainView;
import br.com.fjsistemas.repository.ClienteRepository;
import br.com.fjsistemas.repository.FormaDePagamentoRepository;
import br.com.fjsistemas.repository.ProdutoRepository;
import br.com.fjsistemas.service.VendaService;

@Route(value = "venda-view", layout = MainView.class)
@PageTitle("Lançamento de Vendas")
public class VendaView extends VerticalLayout {

	private static final long serialVersionUID = 1L;

	private HorizontalLayout hltVenda = new HorizontalLayout();
	Grid<Venda> grdVenda = new Grid<>(Venda.class, false);

	private HorizontalLayout hltBarraBotoes = new HorizontalLayout();
	Button btnNovo = new Button("Novo");
	Button btnAlterar = new Button("Alterar");
	Button btnExcluir = new Button("Excluir");

	private Dialog dlgJanela = new Dialog();

	Div superior = new Div();
	Div centro = new Div();
	Div inferior = new Div();

	HorizontalLayout primeiraLinhaDivSuperior = new HorizontalLayout();
	HorizontalLayout segundaLinhaDivSuperior = new HorizontalLayout();
	HorizontalLayout adicionarProdutos = new HorizontalLayout();

	double somaValores;

	@PropertyId("dataVenda")
	private DatePicker txtDataVenda = new DatePicker("Data Venda");

	@PropertyId("cliente")
	private ComboBox<Cliente> txtNomeCliente = new ComboBox<>("Cliente");

	@PropertyId("telefone")
	private TextField txtTelefone = new TextField("Telefone");

	@PropertyId("celular")
	private TextField txtCelular = new TextField("Celular");

	@PropertyId("endereco")
	private TextField txtEndereco = new TextField("Endereço");

	@PropertyId("numero")
	private TextField txtNumero = new TextField("Nº");

	@PropertyId("bairro")
	private TextField txtBairro = new TextField("Bairro");

	@PropertyId("cidade")
	TextField txtCidade = new TextField("Cidade");

	@PropertyId("estado")
	TextField txtEstado = new TextField("Estado");

	@PropertyId("formasPagamento")
	private ComboBox<FormasDePagamento> txtFormasPagamento = new ComboBox<>("Formas de Pagamento");

	@PropertyId("valorTotalVenda")
	private TextField campoSomaValores = new TextField();

	private HorizontalLayout htlDlgBarraBotoes = new HorizontalLayout();
	private Button btnSalvar = new Button("Salvar");
	private Button btnFechar = new Button("Fechar");
	private Button btnAdicionarItem = new Button("+ Item");

	@Autowired
	VendaService vendaService;

	@Autowired
	ClienteRepository clienteRepository;

	@Autowired
	FormaDePagamentoRepository formaDePagamentoRepository;

	@Autowired
	ProdutoRepository produtoRepository;

	private List<Venda> listaVendas;
	private List<TextField> valores = new ArrayList<>();
	private Venda venda;

	Binder<Venda> binderVenda = new Binder<>(Venda.class);

	public VendaView() {

	}

	@PostConstruct
	public void init() {
		configuraTela();

	}

	private void configuraTela() {

		setMargin(false);
		setPadding(false);

		configuraHltVenda();
		configuraFltBarraBotoes();
		configuraDlgJanela();
		populaGrdVenda();
		configuraBinder();

		add(hltVenda, hltBarraBotoes);
	}

	private void configuraFltBarraBotoes() {

		btnNovo.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnNovo.addClickListener(e -> {
			novoClick();
		});

		btnAlterar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnAlterar.addClickListener(e -> {
			alterarClick();
		});

		btnExcluir.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnExcluir.addClickListener(e -> {
			excluirClick();
		});

		hltBarraBotoes.add(btnNovo, btnAlterar, btnExcluir);
	}

	private void excluirClick() {

		if (venda != null) {
			listaVendas.remove(venda);
			vendaService.delete(venda);
			atualizaGrdVenda();
		}
	}

	private void configuraHltVenda() {
		hltVenda.setWidthFull();
		configuraGrdVenda();
		hltVenda.add(grdVenda);
	}

	private void configuraGrdVenda() {
		grdVenda.setHeight("820px");
		grdVenda.setWidthFull();

		grdVenda.addColumn(Venda::getId).setHeader("ID:").setAutoWidth(true);

		grdVenda.addColumn(new LocalDateRenderer<>(Venda::getDataVenda, DateTimeFormatter.ofPattern("dd/MM/yyy")))
				.setHeader("Data Venda").setAutoWidth(true);

		grdVenda.addColumn(venda -> venda.getCliente().getNome()).setHeader("Nome:").setAutoWidth(true)
				.setKey("cliente.nome");

		grdVenda.addColumn(Venda::getValorTotalVenda).setHeader("Valor Total:").setAutoWidth(true)
				.setKey("valorTotalVenda");

		grdVenda.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		grdVenda.getColumns().forEach(col -> col.setAutoWidth(true).setSortable(true).setResizable(true));

		grdVenda.addItemClickListener(e -> {
			venda = e.getItem();
		});

	}

	private void configuraDlgJanela() {

		dlgJanela.setHeightFull();
		dlgJanela.setWidthFull();
		dlgJanela.setCloseOnEsc(false);
		dlgJanela.setCloseOnOutsideClick(false);

		superior.setHeight("170px");
		superior.setWidthFull();

		txtNomeCliente.setWidth("350px");
		txtNomeCliente.setLabel("Nome Cliente");

		txtNomeCliente.setItemLabelGenerator(cliente -> {
			if (cliente == null || cliente.getNome() == null) {
				return " ";

			} else {
				return cliente.getNome();
			}
		});

		List<Cliente> listaDeClientes = clienteRepository.findAll();

		txtNomeCliente.setItems(listaDeClientes);
		txtNomeCliente.addValueChangeListener(event -> {
			if (event.getValue() == null || event.getValue().getFone() == null) {
				txtTelefone.setValue(" ");
			} else {
				txtTelefone.setValue(event.getValue().getFone());
			}
			if (event.getValue() == null || event.getValue().getCelular() == null) {
				txtCelular.setValue(" ");
			} else {
				txtCelular.setValue(event.getValue().getCelular());
			}
			if (event.getValue() == null || event.getValue().getEndereco() == null) {
				txtEndereco.setValue(" ");
			} else {
				txtEndereco.setValue(event.getValue().getEndereco());
			}
			if (event.getValue() == null || event.getValue().getNumero() == null) {
				txtNumero.setValue(" ");
			} else {
				txtNumero.setValue(event.getValue().getNumero());
			}
			if (event.getValue() == null || event.getValue().getBairro() == null) {
				txtBairro.setValue(" ");
			} else {
				txtBairro.setValue(event.getValue().getBairro());
			}
			if (event.getValue() == null || event.getValue().getCidade() == null) {
				txtCidade.setValue(" ");
			} else {
				txtCidade.setValue(event.getValue().getCidade());
			}
			if (event.getValue() == null || event.getValue().getEstado() == null) {
				txtEstado.setValue(" ");
			} else {
				txtEstado.setValue(event.getValue().getEstado());
			}

		});

		new CustomStringBlockFormatter.Builder().blocks(0, 2, 4, 4).delimiters("(", ")", "-").numeric().build()
				.extend(txtTelefone);

		new CustomStringBlockFormatter.Builder().blocks(0, 2, 5, 4).delimiters("(", ")", "-").numeric().build()
				.extend(txtCelular);

		primeiraLinhaDivSuperior.add(txtDataVenda, txtNomeCliente, txtTelefone, txtCelular, txtEndereco, txtNumero,
				txtBairro, txtCidade);

		txtNumero.setWidth("140px");

		txtFormasPagamento.setLabel("Formas de Pagamento");
		List<FormasDePagamento> listaPagamento = formaDePagamentoRepository.findAll();
		txtFormasPagamento.setItemLabelGenerator(FormasDePagamento::getForma);
		txtFormasPagamento.setItems(listaPagamento);

		segundaLinhaDivSuperior.add(txtEstado, txtFormasPagamento);
		superior.add(primeiraLinhaDivSuperior, segundaLinhaDivSuperior);

		centro.setHeight("660px");
		centro.getStyle().set("border-style", "ridge");
		centro.getStyle().set("overflow-y", "scroll");
		centro.setWidthFull();

		btnSalvar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnSalvar.getStyle().set("margin-top", "0em");
		btnSalvar.getStyle().set("margin-left", "1em");
		btnSalvar.addClickListener(e -> {
			salvarClick();
			limparCampos();
		});

		btnFechar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnFechar.getStyle().set("margin-top", "0em");
		btnFechar.addClickListener(e -> {
			dlgJanela.close();
			limparCampos();
		});

		btnAdicionarItem.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnAdicionarItem.getStyle().set("margin-top", "0em");
		btnAdicionarItem.addClickListener(e -> {
			adicionaProduto();
		});

		Label text = new Label("Valor Total");
		text.getElement().getStyle().set("fontWeight", "bold");
		text.getStyle().set("margin-top", "0.8em");
		text.getStyle().set("margin-left", "2em");
		text.getStyle().set("text-align", "center");
		campoSomaValores.getStyle().set("margin-top", "0em");
		campoSomaValores.getStyle().set("margin-right", "0.2em");
		campoSomaValores.setWidth("30em");

		htlDlgBarraBotoes.add(btnSalvar, btnFechar, btnAdicionarItem, text, campoSomaValores);

		inferior.getStyle().set("margin-top", "0px");
		inferior.setHeight("45px");
		inferior.setWidthFull();
		inferior.add(htlDlgBarraBotoes);

		dlgJanela.add(superior, centro, inferior);

	}

	private void salvarClick() {

		venda = binderVenda.getBean();

		boolean adicionarLista = venda.getId() == null ? true : false;

		vendaService.create(venda);

		if (adicionarLista) {
			listaVendas.add(venda);
		}
		atualizaGrdVenda();
		novaVenda();
		txtNomeCliente.focus();

		binderVenda.setBean(venda);

		if (adicionarLista) {
			dlgJanela.close();
		}
	}

	private void populaGrdVenda() {

		listaVendas = vendaService.read();
		atualizaGrdVenda();
	}

	private void atualizaGrdVenda() {
		grdVenda.setItems(listaVendas);
	}

	private void configuraBinder() {

		binderVenda.bindInstanceFields(this);

	}

	private void novoClick() {

		novaVenda();
		binderVenda.setBean(venda);

		dlgJanela.open();
		txtNomeCliente.focus();
	}

	private void alterarClick() {

		if (venda != null) {
			binderVenda.setBean(venda);

			dlgJanela.open();

		}
	}

	private void adicionaProduto() {

		ComboBox<Produto> txtProdutos = new ComboBox<>();

		NumberField txtQuantidade = new NumberField("Quantidade");

		TextField txtValorUnitario = new TextField("Valor Unitário");

		TextField txtValorTotalItem = new TextField("Valor Total Item");

		txtProdutos.setWidth("370px");
		txtProdutos.setLabel("Produtos");
		List<Produto> listaDeProdutos = produtoRepository.findAll();
		txtProdutos.setItemLabelGenerator(Produto::getNome);
		txtProdutos.setItems(listaDeProdutos);
		txtProdutos.addValueChangeListener(event -> {

			NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
			try {

				txtValorUnitario.setValue(formatter.format(event.getValue().getValor()));

			} catch (Exception e) {
				e.printStackTrace();
			}

		});

//==========================================================================================================================

		txtQuantidade.setHasControls(true);
		txtQuantidade.setValue(null);
		txtQuantidade.setMin(1);

		txtQuantidade.addValueChangeListener(event -> {

			NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
			double valorTotal = 0;

			try {
				valorTotal = formatter.parse(txtValorUnitario.getValue()).doubleValue() * txtQuantidade.getValue();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			txtValorTotalItem.setValue(formatter.format(valorTotal));

			double soma = 0;
			for (TextField tf : valores) {
				try {
					soma += formatter.parse(tf.getValue()).doubleValue();

				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

			campoSomaValores.setValue(formatter.format(soma));

		});

		adicionarProdutos = new HorizontalLayout();
		adicionarProdutos.add(txtProdutos, txtQuantidade, txtValorUnitario, txtValorTotalItem);

		centro.add(adicionarProdutos);
		valores.add(txtValorTotalItem);
	}

	private void limparCampos() {
		centro.removeAll();
	}

	private void novaVenda() {
		venda = new Venda();
		venda.setCliente(null);
		dlgJanela.close();

	}
}

Observação: O mesmo erro ocorre quando quero apenas visualizar o pedido, (não altera-lo)…Os produtos estão limpos.

Código para visualizar:

grdVenda.addItemDoubleClickListener(event -> {
			if(venda != null) {
				binderVenda.readBean(venda);
				dlgJanela.open();
			}
		});

Bom dia pessoal, se alguém puder ajudar com esta questão, fico grato…obg!!

@RoinujNosde

Bom dia!!! Vc poderia me ajudar?? Novamente…rs

Você tem algum código pra carregar os produtos da venda e exibi-los?

1 curtida

@RoinujNosde

Eu tenho esse código para cadastrar produtos:

package br.com.fjsistemas.backend;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Produto {
	

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String nome;
	private String marca;
	private String modelo;
	private Double valor;

} 

Tenho este outro código, que é a tela de cadastros de produtos:

package br.com.fjsistemas.cadastros.view;

import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.PropertyId;
import com.vaadin.flow.data.renderer.NumberRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;

import br.com.fjsistemas.backend.Produto;
import br.com.fjsistemas.main.MainView;
import br.com.fjsistemas.service.ProdutoService;

@Route(value = "produto-view", layout = MainView.class)
@PageTitle("Cadastro de Produtos")
public class ProdutoView extends VerticalLayout {

	private static final long serialVersionUID = 1L;
	private HorizontalLayout hltProduto = new HorizontalLayout();
	Grid<Produto> grdProduto = new Grid<>(Produto.class, false);

	private HorizontalLayout hltBarraBotoes = new HorizontalLayout();
	Button btnNovo = new Button("Novo");
	Button btnAlterar = new Button("Alterar");
	Button btnExcluir = new Button("Excluir");

	private Dialog dlgJanela = new Dialog();
	private FormLayout fltCamposProduto = new FormLayout();

	@PropertyId("nome")
	private TextField txtNome = new TextField("Nome");

	@PropertyId("marca")
	private TextField txtMarca = new TextField("Marca");

	@PropertyId("modelo")
	private TextField txtModelo = new TextField("Modelo");

	@PropertyId("valor")
	private NumberField nbfValor = new NumberField("Valor Unitário");

	private HorizontalLayout htlDlgBarraBotoes = new HorizontalLayout();
	private Button btnSalvar = new Button("Salvar");
	private Button btnFechar = new Button("Fechar");

	@Autowired
	ProdutoService produtoService;

	private List<Produto> listaProduto;
	private Produto produto;

	Binder<Produto> binderProduto = new Binder<>(Produto.class);

	public ProdutoView() {

	}

	@PostConstruct
	public void init() {
		configuraTela();

	}

	private void configuraTela() {

		setMargin(false);
		setPadding(false);

		configuraHltProduto();
		configuraFltBarraBotoes();
		configuraDlgJanela();
		populaGrdProduto();
		configuraBinder();

		add(hltProduto, hltBarraBotoes);
	}

	private void configuraFltBarraBotoes() {

		btnNovo.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnNovo.addClickListener(e -> {
			novoClick();
		});

		btnAlterar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnAlterar.addClickListener(e -> {
			alterarClick();
		});

		btnExcluir.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnExcluir.addClickListener(e -> {
			excluirClick();
		});

		hltBarraBotoes.add(btnNovo, btnAlterar, btnExcluir);
	}

	private void excluirClick() {

		if (produto != null) {
			listaProduto.remove(produto);
			produtoService.delete(produto);
			atualizaGrdProduto();
		}
	}

	private void configuraHltProduto() {
		hltProduto.setWidthFull();
		configuraGrdProduto();
		hltProduto.add(grdProduto);
	}

	private void configuraGrdProduto() {
		grdProduto.setHeight("820px");
		grdProduto.setWidthFull();
	
		
		grdProduto.addColumn(Produto::getId).setHeader("ID:").setAutoWidth(true);

		grdProduto.addColumn(Produto::getNome).setHeader("Produto:").setAutoWidth(true).setKey("nome");

		grdProduto.addColumn(Produto::getMarca).setHeader("Marca:").setAutoWidth(true).setKey("marca");

		grdProduto.addColumn(Produto::getModelo).setHeader("Modelo:").setAutoWidth(true).setKey("modelo");
		
		grdProduto.addColumn(new NumberRenderer<>(Produto::getValor, "R$ %(,.2f", Locale.getDefault(), "R$ 0.00"))
				.setHeader("Valor Unitário:").setAutoWidth(true).setKey("valor");

		grdProduto.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		grdProduto.getColumns().forEach(col -> col.setAutoWidth(true).setSortable(true).setResizable(true));
		
		grdProduto.addItemClickListener(e -> {
			produto = e.getItem();
		});

	}

	private void configuraDlgJanela() {

		btnSalvar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnSalvar.getStyle().set("margin-top", "25px");
		btnSalvar.addClickListener(e -> {
			salvarClick();
		});

		btnFechar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnFechar.getStyle().set("margin-top", "25px");
		btnFechar.addClickListener(e -> {
			dlgJanela.close();
		});
		
		fltCamposProduto.add(txtNome, txtMarca, txtModelo, nbfValor);
		htlDlgBarraBotoes.add(btnSalvar, btnFechar);

		dlgJanela.add(fltCamposProduto, htlDlgBarraBotoes);
	}

	private void salvarClick() {

		produto = binderProduto.getBean();

		boolean adicionarLista = produto.getId() == null ? true : false;

		produtoService.create(produto);

		if (adicionarLista) {
			listaProduto.add(produto);
		}
		atualizaGrdProduto();
		novoProduto();
		txtNome.focus();

		binderProduto.setBean(produto);

		if (adicionarLista) {
			dlgJanela.close();
		}
	}

	private void populaGrdProduto() {

		listaProduto = produtoService.read();
		atualizaGrdProduto();
	}

	private void atualizaGrdProduto() {
		grdProduto.setItems(listaProduto);
	}

	private void configuraBinder() {

		binderProduto.bindInstanceFields(this);
		binderProduto.toString().toUpperCase();

	}

	private void novoClick() {

		novoProduto();
		binderProduto.setBean(produto);

		dlgJanela.open();
		txtNome.focus();
	}

	private void alterarClick() {

		if (produto != null) {
			binderProduto.setBean(produto);

			dlgJanela.open();

		}
	}

	private void novoProduto() {
		produto = new Produto();
		produto.setNome(" ");
		dlgJanela.close();

	}
}

e aqui, tenho o código da tela de vendas, e neste código vendas acabo chamando a classe produto para realizar a venda…veja o metodo adicionaProduto();

package br.com.fjsistemas.compraVenda;

import java.text.NumberFormat;
import java.text.ParseException;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.textfieldformatter.CustomStringBlockFormatter;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.PropertyId;
import com.vaadin.flow.data.renderer.LocalDateRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;

import br.com.fjsistemas.backend.Cliente;
import br.com.fjsistemas.backend.FormaDePagamento;
import br.com.fjsistemas.backend.Produto;
import br.com.fjsistemas.backend.Venda;
import br.com.fjsistemas.main.MainView;
import br.com.fjsistemas.repository.ClienteRepository;
import br.com.fjsistemas.repository.FormaDePagamentoRepository;
import br.com.fjsistemas.repository.ProdutoRepository;
import br.com.fjsistemas.service.VendaService;

@Route(value = "venda-view", layout = MainView.class)
@PageTitle("Lançamento de Vendas")
public class VendaView extends VerticalLayout {

	private static final long serialVersionUID = 1L;

	private HorizontalLayout hltVenda = new HorizontalLayout();
	Grid<Venda> grdVenda = new Grid<>(Venda.class, false);

	private HorizontalLayout hltBarraBotoes = new HorizontalLayout();
	Button btnNovo = new Button("Novo");
	Button btnAlterar = new Button("Alterar");
	Button btnExcluir = new Button("Excluir");

	private Dialog dlgJanela = new Dialog();

	Div superior = new Div();
	Div centro = new Div();
	Div inferior = new Div();

	HorizontalLayout primeiraLinhaDivSuperior = new HorizontalLayout();
	HorizontalLayout segundaLinhaDivSuperior = new HorizontalLayout();
	HorizontalLayout adicionarProdutos = new HorizontalLayout();

	double somaValores;

	@PropertyId("dataVenda")
	private DatePicker txtDataVenda = new DatePicker("Data Venda");

	@PropertyId("cliente")
	private ComboBox<Cliente> txtNomeCliente = new ComboBox<>("Cliente");

	@PropertyId("telefone")
	private TextField txtTelefone = new TextField("Telefone");

	@PropertyId("celular")
	private TextField txtCelular = new TextField("Celular");

	@PropertyId("endereco")
	private TextField txtEndereco = new TextField("Endereço");

	@PropertyId("numero")
	private TextField txtNumero = new TextField("Nº");

	@PropertyId("bairro")
	private TextField txtBairro = new TextField("Bairro");

	@PropertyId("cidade")
	TextField txtCidade = new TextField("Cidade");

	@PropertyId("estado")
	TextField txtEstado = new TextField("Estado");

	@PropertyId("formaDePagamento")
	private ComboBox<FormaDePagamento> txtFormasPagamento = new ComboBox<>("Formas de Pagamento");
	
	//@PropertyId("produtoVendido")
	//private ComboBox<ProdutoVendido> txtProdutoVendido = new ComboBox<>();

	@PropertyId("valorTotalVenda")
	private TextField campoSomaValores = new TextField();

	private HorizontalLayout htlDlgBarraBotoes = new HorizontalLayout();
	private Button btnSalvar = new Button("Salvar");
	private Button btnFechar = new Button("Fechar");
	private Button btnAdicionarItem = new Button("+ Item");

	@Autowired
	VendaService vendaService;

	@Autowired
	ClienteRepository clienteRepository;

	@Autowired
	FormaDePagamentoRepository formaDePagamentoRepository;
	
	//@Autowired
	//ProdutoVendidoRepository produtoVendidoRepository;

	@Autowired
	ProdutoRepository produtoRepository;

	private List<Venda> listaVendas;
	private List<TextField> valores = new ArrayList<>();
	private Venda venda;

	Binder<Venda> binderVenda = new Binder<>(Venda.class);

	public VendaView() {

	}

	@PostConstruct
	public void init() {
		configuraTela();

	}

	private void configuraTela() {

		setMargin(false);
		setPadding(false);

		configuraHltVenda();
		configuraFltBarraBotoes();
		configuraDlgJanela();
		populaGrdVenda();
		configuraBinder();

		add(hltVenda, hltBarraBotoes);
	}

	private void configuraFltBarraBotoes() {

		btnNovo.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnNovo.addClickListener(e -> {
			novoClick();
		});

		btnAlterar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnAlterar.addClickListener(e -> {
			alterarClick();
		});

		btnExcluir.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnExcluir.addClickListener(e -> {
			excluirClick();
		});

		hltBarraBotoes.add(btnNovo, btnAlterar, btnExcluir);
	}

	private void excluirClick() {

		if (venda != null) {
			listaVendas.remove(venda);
			vendaService.delete(venda);
			atualizaGrdVenda();
		}
	}

	private void configuraHltVenda() {
		hltVenda.setWidthFull();
		configuraGrdVenda();
		hltVenda.add(grdVenda);
	}

	private void configuraGrdVenda() {
		grdVenda.setHeight("820px");
		grdVenda.setWidthFull();

		grdVenda.addColumn(Venda::getId).setHeader("ID:").setAutoWidth(true);

		grdVenda.addColumn(new LocalDateRenderer<>(Venda::getDataVenda, DateTimeFormatter.ofPattern("dd/MM/yyy")))
				.setHeader("Data Venda").setAutoWidth(true);

		grdVenda.addColumn(venda -> venda.getCliente().getNome()).setHeader("Nome:").setAutoWidth(true)
				.setKey("cliente.nome");

		grdVenda.addColumn(Venda::getValorTotalVenda).setHeader("Valor Total:").setAutoWidth(true)
				.setKey("valorTotalVenda");

		grdVenda.addColumn(venda -> venda.getFormaDePagamento().getFormaDePagamento()).setHeader("Forma de Pagamento")
				.setAutoWidth(true).setKey("formaDePagamento");

		grdVenda.addThemeVariants(GridVariant.LUMO_COMPACT, GridVariant.LUMO_COLUMN_BORDERS);

		grdVenda.getColumns().forEach(col -> col.setAutoWidth(true).setSortable(true).setResizable(true));

		grdVenda.addItemClickListener(e -> {
			venda = e.getItem();
		});

		grdVenda.addItemDoubleClickListener(event -> {
			if (venda != null) {
				binderVenda.readBean(venda);
				dlgJanela.open();

			}
		});

	}

	private void configuraDlgJanela() {

		dlgJanela.setHeightFull();
		dlgJanela.setWidthFull();
		dlgJanela.setCloseOnEsc(false);
		dlgJanela.setCloseOnOutsideClick(false);

		superior.setHeight("170px");
		superior.setWidthFull();

		txtNomeCliente.setWidth("350px");
		txtNomeCliente.setLabel("Nome Cliente");

		txtNomeCliente.setItemLabelGenerator(cliente -> {
			if (cliente == null || cliente.getNome() == null) {
				return " ";

			} else {
				return cliente.getNome();
			}
		});

		List<Cliente> listaDeClientes = clienteRepository.findAll();

		txtNomeCliente.setItems(listaDeClientes);
		txtNomeCliente.addValueChangeListener(event -> {
			if (event.getValue() == null || event.getValue().getFone() == null) {
				txtTelefone.setValue(" ");
			} else {
				txtTelefone.setValue(event.getValue().getFone());
			}
			if (event.getValue() == null || event.getValue().getCelular() == null) {
				txtCelular.setValue(" ");
			} else {
				txtCelular.setValue(event.getValue().getCelular());
			}
			if (event.getValue() == null || event.getValue().getEndereco() == null) {
				txtEndereco.setValue(" ");
			} else {
				txtEndereco.setValue(event.getValue().getEndereco());
			}
			if (event.getValue() == null || event.getValue().getNumero() == null) {
				txtNumero.setValue(" ");
			} else {
				txtNumero.setValue(event.getValue().getNumero());
			}
			if (event.getValue() == null || event.getValue().getBairro() == null) {
				txtBairro.setValue(" ");
			} else {
				txtBairro.setValue(event.getValue().getBairro());
			}
			if (event.getValue() == null || event.getValue().getCidade() == null) {
				txtCidade.setValue(" ");
			} else {
				txtCidade.setValue(event.getValue().getCidade());
			}
			if (event.getValue() == null || event.getValue().getEstado() == null) {
				txtEstado.setValue(" ");
			} else {
				txtEstado.setValue(event.getValue().getEstado());
			}

		});

		new CustomStringBlockFormatter.Builder().blocks(0, 2, 4, 4).delimiters("(", ")", "-").numeric().build()
				.extend(txtTelefone);

		new CustomStringBlockFormatter.Builder().blocks(0, 2, 5, 4).delimiters("(", ")", "-").numeric().build()
				.extend(txtCelular);

		primeiraLinhaDivSuperior.add(txtDataVenda, txtNomeCliente, txtTelefone, txtCelular, txtEndereco, txtNumero,
				txtBairro, txtCidade);

		txtNumero.setWidth("140px");

		txtFormasPagamento.setLabel("Formas de Pagamento");

		List<FormaDePagamento> listaPagamento = formaDePagamentoRepository.findAll();
		txtFormasPagamento.setItemLabelGenerator(FormaDePagamento::getFormaDePagamento);
		txtFormasPagamento.setItems(listaPagamento);

		segundaLinhaDivSuperior.add(txtEstado, txtFormasPagamento);
		superior.add(primeiraLinhaDivSuperior, segundaLinhaDivSuperior);

		centro.setHeight("660px");
		centro.getStyle().set("border-style", "ridge");
		centro.getStyle().set("overflow-y", "scroll");
		centro.setWidthFull();

		btnSalvar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnSalvar.getStyle().set("margin-top", "0em");
		btnSalvar.getStyle().set("margin-left", "1em");
		btnSalvar.addClickListener(e -> {
			salvarClick();

		});

		btnFechar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnFechar.getStyle().set("margin-top", "0em");
		btnFechar.addClickListener(e -> {
			dlgJanela.close();
			limparCampos();
		});

		btnAdicionarItem.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
		btnAdicionarItem.getStyle().set("margin-top", "0em");
		btnAdicionarItem.addClickListener(e -> {
			adicionaProduto();
		});

		Label text = new Label("Valor Total");
		text.getElement().getStyle().set("fontWeight", "bold");
		text.getStyle().set("margin-top", "0.8em");
		text.getStyle().set("margin-left", "2em");
		text.getStyle().set("text-align", "center");
		campoSomaValores.getStyle().set("margin-top", "0em");
		campoSomaValores.getStyle().set("margin-right", "0.2em");
		campoSomaValores.setWidth("30em");

		htlDlgBarraBotoes.add(btnSalvar, btnFechar, btnAdicionarItem, text, campoSomaValores);

		inferior.getStyle().set("margin-top", "0px");
		inferior.setHeight("45px");
		inferior.setWidthFull();
		inferior.add(htlDlgBarraBotoes);

		dlgJanela.add(superior, centro, inferior);

	}

	private void salvarClick() {

		venda = binderVenda.getBean();

		boolean adicionarLista = venda.getId() == null ? true : false;

		vendaService.create(venda);

		if (adicionarLista) {
			listaVendas.add(venda);

		}
		atualizaGrdVenda();
		novaVenda();
		txtNomeCliente.focus();

		binderVenda.setBean(venda);

		if (adicionarLista) {

			dlgJanela.close();
		}
	}

	private void populaGrdVenda() {

		listaVendas = vendaService.read();
		atualizaGrdVenda();
	}

	private void atualizaGrdVenda() {
		grdVenda.setItems(listaVendas);
	}

	private void configuraBinder() {

		binderVenda.bindInstanceFields(this);

	}

	private void novoClick() {

		novaVenda();
		binderVenda.setBean(venda);

		dlgJanela.open();
		txtNomeCliente.focus();
	}

	private void alterarClick() {

		if (venda != null) {
			binderVenda.setBean(venda);

			dlgJanela.open();

		}
	}

	private void adicionaProduto() {

		ComboBox<Produto> txtProdutos = new ComboBox<>();

		NumberField txtQuantidade = new NumberField("Quantidade");

		TextField txtValorUnitario = new TextField("Valor Unitário");

		TextField txtValorTotalItem = new TextField("Valor Total Item");

		txtProdutos.setWidth("370px");
		txtProdutos.setLabel("Produtos");
		List<Produto> listaDeProdutos = produtoRepository.findAll();
		txtProdutos.setItemLabelGenerator(Produto::getNome);
		txtProdutos.setItems(listaDeProdutos);
		txtProdutos.addValueChangeListener(event -> {

			NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
			try {

				txtValorUnitario.setValue(formatter.format(event.getValue().getValor()));

			} catch (Exception e) {
				e.printStackTrace();
			}

		});

//==========================================================================================================================

		txtQuantidade.setHasControls(true);
		txtQuantidade.setValue(null);
		txtQuantidade.setMin(1);

		txtQuantidade.addValueChangeListener(event -> {

			NumberFormat formatter = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
			double valorTotal = 0;

			try {
				valorTotal = formatter.parse(txtValorUnitario.getValue()).doubleValue() * txtQuantidade.getValue();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			txtValorTotalItem.setValue(formatter.format(valorTotal));

			double soma = 0;
			for (TextField tf : valores) {
				try {
					soma += formatter.parse(tf.getValue()).doubleValue();

				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

			campoSomaValores.setValue(formatter.format(soma));

		});
				
		adicionarProdutos = new HorizontalLayout();
		adicionarProdutos.add(txtProdutos, txtQuantidade, txtValorUnitario, txtValorTotalItem);
		
		centro.add(adicionarProdutos);
		valores.add(txtValorTotalItem);
	}

	private void limparCampos() {
		centro.removeAll();
	}

	private void novaVenda() {
		venda = new Venda();
		venda.setCliente(null);
		venda.setFormaDePagamento(null);
		dlgJanela.close();

	}
}

agora eu fiquei na duvida se deveria criar uma classe, por exemplo ProdutoVendido com seus atributos(nome, quantidade, valorunitario e valorTotal)…ou se eu uso a classe venda(que é a resposavel por armazenar as vendas)

Classe Venda:

package br.com.fjsistemas.backend;

import java.time.LocalDate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Venda {

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

	private LocalDate dataVenda = LocalDate.now();

	@ManyToOne
	private Cliente cliente;
	
	@ManyToOne
	private FormaDePagamento formaDePagamento;
	
	private String valorTotalVenda;
}

Eu quero dizer: você vai clicar numa venda, o programa pega os dados dela do banco e armazena na sua entidade Venda.
Nessa entidade tem uma lista de produtos, certo?
Você não parece estar fazendo nenhum carregamento desses produtos na tela, por isso dá esse problema.
O único método que você tem é adicionarProduto(), mas esse sozinho não “dá conta”.

1 curtida

@RoinujNosde

não…na entidade Venda não há uma lista, então neste caso o primeiro passo será criar uma List

private List<Produto> produtoVendido = new ArrayList<>();

é isso?

Sim, você vai por alguma anotação nela também.

1 curtida

@RoinujNosde

com relação a anotação, não sei se meu pensamento está correto, me corrija caso esteja…

Como podem ser muitos produtos para uma venda a anotação deve ser

@ManyToOne?

Se for fazer a classe ProdutoVendido (que é interessante), acho que seria OneToMany.

1 curtida

@RoinujNosde

Ok então ficou assim minha entidade Venda:

package br.com.fjsistemas.backend;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Venda {

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

	private LocalDate dataVenda = LocalDate.now();

	@ManyToOne
	private Cliente cliente;
	
	@ManyToOne
	private FormaDePagamento formaDePagamento;
	
	@OneToMany 
	private List<Produto> produtoVendido = new ArrayList<>();
	
	private String valorTotalVenda;
}

Até aqui ta tudo certo?

Não ia ser a classe ProdutoVendido?

1 curtida

@RoinujNosde

eu tinha entendido que era pra fazer a lista na classe venda…mas não por isso…então só pra deixar claro, na classe Venda não haverá nenhuma lista, correto?

Vou criar uma classe ProdutoVendido, com os atributos e a lista…correto?

@RoinujNosde

se estiver tudo correto, ficou assim:

package br.com.fjsistemas.backend;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class ProdutoVendido {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private String produtoVendido;
	private String quantidadeVendida;
	private Double valorUnitarioVendido;
	private Double valorTotalVendido;
	
	@OneToMany
	private List<Produto> listaVendidos = new ArrayList<>();
}
Classe Venda:
    private List<ProdutoVendido> produtos
1 curtida

@RoinujNosde

Classe Venda:

package br.com.fjsistemas.backend;

import java.time.LocalDate;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Venda {

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

	private LocalDate dataVenda = LocalDate.now();

	@ManyToOne
	private Cliente cliente;
	
	@ManyToOne
	private FormaDePagamento formaDePagamento;
	
	@OneToMany
private List<ProdutoVendido> produtos;
	
	private String valorTotalVenda;
} 

Classe ProdutoVendido:

package br.com.fjsistemas.backend;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class ProdutoVendido {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private String produtoVendido;
	private String quantidadeVendida;
	private Double valorUnitarioVendido;
	private Double valorTotalVendido;
	
	
}

Correto?

Acredito que sim.
Agora precisa implementar uma lógica para carregar esses produtos na tela quando for alterar/exibir a Venda

1 curtida

@RoinujNosde

algo assim por exemplo?:

Na classe Venda:

package br.com.fjsistemas.backend;

import java.time.LocalDate;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Venda {

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

	private LocalDate dataVenda = LocalDate.now();

	@ManyToOne
	private Cliente cliente;

	@ManyToOne
	private FormaDePagamento formaDePagamento;

	@OneToMany
	private List<ProdutoVendido> produtos;
	
	public void addProduto(Produto produto) {
		ProdutoVendido produtoVenda = new ProdutoVendido(this, produto);
		produtos.add(produtoVenda);
	}

	private String valorTotalVenda;
}

Classe ProdutoVendido

package br.com.fjsistemas.backend;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class ProdutoVendido {
	
	

	public ProdutoVendido(Venda venda, Produto produto) {
		super();
		this.venda = venda;
		this.produto = produto;
	}
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private String produtoVendido;
	private String quantidadeVendida;
	private Double valorUnitarioVendido;
	private Double valorTotalVendido;
	
	private Venda venda;
	private Produto produto;

}

Correto desta forma?

Aparentemente sim

1 curtida