Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

varios produto para uma compra

Opa eu estava fazendo um programa para teste, e quando eu fui salvar a venda salvo tudo normal! só que do jeito que eu fiz não tinha a opção de salvar mais de uma venda, mais na modelagem fiz para varias vendas, alguem pode me ajudar como ou salvar mais de uma venda? Penso tipo você escolhe o produto a quantidade e depois já joga no seu preço total a soma dai, ai quero ter a opçao de ter como adicionar outro produto

11 respostas

Oi Alisson, pode colar as classes Produto e Venda para ficar um pouco mais claro para nós? Assim consigo te ajudar melhor.

Abraços e bons estudos.

Opa renan vlw por me ajudar, não é uma duvida e sim uma base, como falado acima, tenho a classe produto compra e compraProduto, na classe compra.

@SuppressWarnings("serial")
@Entity
public class Compra implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    private Double precoTotal;
    private Double valor;
    private Calendar Data = Calendar.getInstance();
    @ManyToMany
    private List<Produto> produtos = new ArrayList<Produto>();
    @OneToOne
    @JoinColumn(name = "formaDePagamento_codigo")
    private FormaDePagamento formaDePagamento = new FormaDePagamento();
    @OneToOne
    @JoinColumn(name = "quantidadeParcela_codigo")
    private QuantidadeParcela quantidadeParcela = new QuantidadeParcela();
    private Double valorParcela;

na compra posso ter varios produtos correto? agora na classe produto.

@Entity
@SuppressWarnings("serial")
public class Produto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    private String nome;
    private Double preco;
    private Double precoAVender;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fornecedor_codigo")
    private Fornecedor fornecedor = new Fornecedor();
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "marca_codigo")
    private Marca marca = new Marca();
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "estoque_codigo")
    private Estoque estoque = new Estoque();

aqui irá gerar uma tabela associativa, que eu estou usando ela assim.

@Entity
@SuppressWarnings("serial")
public class Compra_produto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    @ManyToOne
    @JoinColumn(name = "Compra_codigo", nullable = true)
    private Compra compra = new Compra();
    @ManyToOne
    @JoinColumn(name = "produtos_codigo", nullable = true)
    private Produto produto = new Produto();
    private Integer quantidade;

Correto? Aqui sem nenhuma duvida e nenhum erro, depois tenho o meu bean, que é a compra.

@Named(value = "compraBean")
@ViewScoped
@SuppressWarnings("serial")
public class CompraBean implements Serializable {

    @Inject
    private ProdutoDao produtoDao;
    @Inject
    private Compra_produto compraProduto;
    @Inject
    private Compra compra;
    @Inject
    private Produto produto;
    @Inject
    private CompraProdutoDao compraProdutoDao;
    @Inject
    private FormaDePagamentoDao formaDePagamentoDao;
    @Inject
    private QuantidadeParcelaDao quantidadeParcelaDao;
    @Inject
    private CompraDao compraDao;
    private List<Compra_produto> compraProdutos = new ArrayList<Compra_produto>();

    @Transacional
    public void salvar() {
        if(compra.getCodigo() == null) {
            compraDao.salvar(compra);
            Compra compraCodigo = compraDao.buscarPorCodigo(compra.getCodigo());
            compraProduto.setCompra(compraCodigo);
            compraProdutoDao.salvar(compraProduto);
            Mensagem.mensagemInfo("Compra realizado com sucesso");
        } else {

        }
        this.compra = new Compra();
        this.compraProduto = new Compra_produto();
    }

    @Transacional
    public List<FormaDePagamento> getListaPagamentos() {
        return formaDePagamentoDao.lista();
    }

    @Transacional
    public List<QuantidadeParcela> getListaParcelas() {
        return quantidadeParcelaDao.lista();
    }

    @Transacional
    public List<Compra_produto> getListaCompraProdutos() {
        return compraProdutoDao.lista();
    }

    @Transacional
    public List<Produto> getListaProdutos() {
        return produtoDao.listaProdutos();
    }

    @SuppressWarnings("unused")
    @Transacional
    public void valorProduto() {
        List<Produto> produtos = produtoDao.listaProdutos();
        for (Produto produto : produtos) {
            compra.setPrecoTotal(compraProduto.getQuantidade()
                    * compraProduto.getProduto().getPreco());
        }
        System.out.println("Preço total da compra: "
                + this.compra.getPrecoTotal());
    }

    @SuppressWarnings("unused")
    public void somarParcela() {
        List<QuantidadeParcela> parcelas = quantidadeParcelaDao.lista();
        for (QuantidadeParcela quantidadeParcela : parcelas) {
            compra.setValorParcela(compra.getPrecoTotal()
                    / compra.getQuantidadeParcela().getQuantidadeParcela());
        }
        System.out.println("Preço total parcela: "
                + this.compra.getPrecoTotal());
    }

    public void carregarProduto(Produto produto) {
        this.produto = produto;
    }

depois meu html

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

<ui:composition template="/template/template.xhtml">
    <ui:define name="conteudo">
        <h:form>
            <p:dataTable>
                <f:facet name="header">
                    <p:commandButton value="Compra" oncomplete="PF('compra').show();" />
                </f:facet>
            </p:dataTable>
        </h:form>

        <p:dialog widgetVar="compra" modal="true" appendTo="@(body)"
            resizable="false" closable="true" draggable="false" header="Compra">
            <h:form id="formularioCompra">
                <h:panelGrid columns="2">
                    <p:outputLabel value="Produto: " for="produto" />
                    <p:selectOneMenu id="produto"
                        value="#{compraBean.compraProduto.produto}"
                        converter="produtoConverter">
                        <f:selectItem itemValue="" itemLabel="Selecione..." />
                        <f:selectItems value="#{compraBean.listaProdutos}" var="produto"
                            itemValue="#{produto}" itemLabel="#{produto.nome}" />
                        <p:ajax listener="#{compraBean.carregarProduto(produto)}"
                            update="precoUnitario" />
                    </p:selectOneMenu>

                    <p:outputLabel value="Preço unitario: " for="precoUnitario" />
                    <p:inputText id="precoUnitario"
                        value="#{compraBean.compraProduto.produto.preco}" readonly="true" />

                    <p:outputLabel value="Quantidade: " for="quantidade" />
                    <p:inputText id="quantidade"
                        value="#{compraBean.compraProduto.quantidade}">
                        <p:ajax listener="#{compraBean.valorProduto}" update="valorTotal" />
                    </p:inputText>

                    <p:outputLabel value="Valor Total: " for="valorTotal" />
                    <p:inputText id="valorTotal"
                        value="#{compraBean.compra.precoTotal}" />

                    <p:outputLabel value="Data: " for="data" />
                    <p:calendar id="data" value="#{compraBean.compra.data.time}">
                        <f:convertDateTime pattern="dd/MM/yyyy" />
                    </p:calendar>

                    <p:outputLabel value="Pagamento: " for="pagamento" />
                    <p:selectOneMenu id="pagamento"
                        value="#{compraBean.compra.formaDePagamento}"
                        converter="formaDePagamentoConverter">
                        <f:selectItem itemValue="" itemLabel="Selecione..." />
                        <f:selectItems value="#{compraBean.listaPagamentos}"
                            var="pagamento" itemValue="#{pagamento}"
                            itemLabel="#{pagamento.descricao}" />
                    </p:selectOneMenu>

                    <p:outputLabel value="Parcela: " for="parcela" />
                    <p:selectOneMenu id="parcela"
                        value="#{compraBean.compra.quantidadeParcela}"
                        converter="quantidadeParcelaConveter">
                        <f:selectItem itemValue="" itemLabel="Selecione..." />
                        <f:selectItems value="#{compraBean.listaParcelas}" var="parcela"
                            itemValue="#{parcela}" itemLabel="#{parcela.quantidadeParcela}" />
                        <p:ajax listener="#{compraBean.somarParcela}"
                            update="valorParcela" />
                    </p:selectOneMenu>

                    <p:outputLabel value="Valor parcela: " for="valorParcela" />
                    <p:inputText id="valorParcela"
                        value="#{compraBean.compra.valorParcela}" readonly="true" />
                </h:panelGrid>
                <p:commandButton value="Salvar"
                    actionListener="#{compraBean.salvar}" update="formularioCompra" />
            </h:form>
        </p:dialog>
    </ui:define>
</ui:composition>
</html>

Ta salvando validando os campos tudo correto até aqui também não tenho nenhuma duvida, agora o jeito que estou fazendo ai encima, só estou conseguindo fazer compra de um produto, eu queria na hora da compra "adicionar" produto não só um, como por exemplo essa imagem.

https://www.google.com.br/search?q=tela+de+compra+sistema+web&tbm=isch&tbo=u&source=univ&sa=X&ved=0ahUKEwjW-a3M4uzSAhVGl5AKHaYdCbMQsAQIKA&biw=1360&bih=638#imgdii=7olrbv96OIFDHM:&imgrc=47woAhpolxBHxM:

Certo que essa imagem é de venda, mais é a mesma lófica que eu quero, ta vendo que ele tem um botão de inserir? e depois uma tabela mostrando os produtos que ele ta vendendo? Pode ver que tem 2 produtos, e eu quero é a mesma coisa. Querer comprar varios produtos por vez e não um por um como estou fazendo, mais não sei nem por onde começar a fazer isso, deu pra entender?

Agora eu entendi, vamos lá. Uma abordagem é criar um método adicionarProduto que a única coisa que ele vai fazer é adicionar produtos nessa lista:

private List<Compra_produto> compraProdutos

E no seu método salvar você persiste a compra e todos os elementos dessa lista.

Qualquer dúvida só comentar aqui embaixo.

Abraços e bons estudos.

Renam crio uma lista de compra_produto e depois crio um metodo,

public void adicionaProduto() {
    compraProduto.add();
}

Desse jeito não vem nada nele, certo? o metodo correto seria?

public void adicionaProduto(Produto produto) {
    compraProduto.add(produto);
}

ou dessa forma? Estou perdido em questão de adicionar varios produtos, e fazer uma tabela na hora de ver oque estou comprando :( nunca fiz isso deve ser falta de experiencia :(

public void adicionarProduto() {
        compraProdutos.add(compraProduto);
    }

Só que aqui o java vai reclamar correto? e no meu html é necessario eu ter uma tabela de produto? para passar como parametro pro meu bean?

Opa fazendo alguns teste aqui acho que clareou e estou indo pro rumo certo, poderia ver se está correto? obrigado, não terminei mais pelo menos estou conseguindo ver os meus produtos que estou comprando.

public void adicionarProduto() {
        compraProdutos.add(compraProduto);
        this.compraProduto = new Compra_produto();
    }
<p:commandButton value="Inserir"
                        actionListener="#{compraBean.adicionarProduto}"
                        update="formularioItens" />
                </h:panelGrid>
            </h:form>

            <h:form id="formularioItens">
                <p:dataTable value="#{compraBean.compraProdutos}"
                    var="compraProduto" paginator="true" rows="4"
                    emptyMessage="Nenhum compra">
                    <p:column>
                        <h:outputText value="#{compraProduto.produto.nome}" />
                    </p:column>        
                </p:dataTable>
            </h:form>

Opa consegui fazer oque queria agora o meu erro está dando esse aqui, na hora de salvar aparece o erro.

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'produtos_codigo' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    ... 90 more
@Transacional
    public void salvar() {
        if (compra.getCodigo() == null) {
            compraDao.salvar(compra);
            Compra compraCodigo = compraDao.buscarPorCodigo(compra.getCodigo());
            compraProduto.setCompra(compraCodigo);
            compraProdutoDao.salvar(compraProduto);
            Mensagem.mensagemInfo("Compra realizado com sucesso");
        } else {

        }
        this.compra = new Compra();
        this.compraProduto = new Compra_produto();
    }

Verifica se todas as instâncias de Compra_produto estão com o atributo Produto preenchido, esse erro acontece quando o Produto está com null.

Abraços e bons estudos.

Opa, então não sei oque pode ser, poderia verificar o código pra ver se está correto? sera que eu não to esquecendo de algo? o metodo salvar está correto? aqui o meu metodo que fiz...

public void adicionarProduto() {
        compraProdutos.add(compraProduto);
        Double aux = 0.0;
        this.compraProduto = new Compra_produto();
        for (Compra_produto p : compraProdutos) {
            compra.setValor(p.getProduto().getPreco() * p.getQuantidade());
            aux += p.getProduto().getPreco() * p.getQuantidade();
            compra.setPrecoTotal(aux);
        }
        System.out.println(aux);
    }

fiz esse metodo e está correto? e depois fiz no meu html...

<h:panelGrid columns="6">
                    <p:commandButton value="Inserir"
                        actionListener="#{compraBean.adicionarProduto}"
                        update="formularioCompra :formularioItens">
                    </p:commandButton>
                </h:panelGrid>
            </h:form>

            <h:form id="formularioItens">
                <p:dataTable value="#{compraBean.compraProdutos}"
                    var="compraProduto" paginator="true" rows="3"
                    emptyMessage="Nenhum compra">
                    <p:column headerText="Produto">
                        <h:outputText value="#{compraProduto.produto.nome}" />
                    </p:column>
                    <p:column headerText="Preço unitario">
                        <h:outputText value="#{compraProduto.produto.preco}" />
                    </p:column>
                    <p:column headerText="Quantidade">
                        <h:outputText value="#{compraProduto.quantidade}" />
                    </p:column>
                </p:dataTable>
                <h:panelGrid columns="6">
                    <p:outputLabel value="Valor: " for="valor" />
                    <p:inputText id="valor" value="#{compraBean.compra.valor}" size="7">
                    </p:inputText>
                    <p:outputLabel value="Valor total da compra: " for="valorTotal" />
                    <p:inputText id="valorTotal"
                        value="#{compraBean.compra.precoTotal}" size="8" />
                </h:panelGrid>
                <p:commandButton value="Finalizar"
                    actionListener="#{compraBean.salvar}" />
            </h:form>

depois meu metodo salvar.

    @Transacional
    public void salvar() {
        if (compra.getCodigo() == null) {
            compraDao.salvar(compra);
            Compra compraCodigo = compraDao.buscarPorCodigo(compra.getCodigo());
            compraProduto.setCompra(compraCodigo);
            compraProdutoDao.salvar(compraProduto);
            Mensagem.mensagemInfo("Compra realizado com sucesso");
        } else {

        }
        this.compra = new Compra();
        this.compraProduto = new Compra_produto();
    }

Tá correto, era assim que você me disse?

Sera que não estou errando no meu metodo adicionar? não deveria adicionar o produto envez do compraProduto?

public void adicionarProduto() {
        compraProdutos.add(compraProduto);

Tava fazendo um teste aqui, e o erro que falei pra você da colluna nulla tava vindo por essa parte do código na minha tabela compra_produto. Elá tava desse jeito.

@Entity
@SuppressWarnings("serial")
public class Compra_produto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    @ManyToOne
    @JoinColumn(name = "Compra_codigo", nullable = true)
    private Compra compra = new Compra();
    @ManyToOne
    @JoinColumn(name = "produtos_codigo", nullable = true)
    private Produto produto = new Produto();
    private Integer quantidade;

tirei a parte do

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

Deixando ela assim.

@ManyToOne
    @JoinColumn(name = "Compra_codigo", nullable = true)
    private Compra compra = new Compra();
    @ManyToOne
    @JoinColumn(name = "produtos_codigo", nullable = true)
    private Produto produto = new Produto();
    private Integer quantidade;

dai tive que deixar assim a tabela porque tava me acusando que na tabela não tinha um identificador, fiz correto deixar assim?

@Entity
@SuppressWarnings("serial")
public class Compra_produto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ManyToOne
    @JoinColumn(name = "Compra_codigo", nullable = true)
    private Compra compra = new Compra();
    @ManyToOne
    @JoinColumn(name = "produtos_codigo", nullable = true)
    private Produto produto = new Produto();
    private Integer quantidade;

ai quando tento salvar o erro é esse.

Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: br.com.bercalini.modelo.Compra_produto.produto -> br.com.bercalini.modelo.Produto
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
    ... 50 more

Mais eu ja tenho no meu html a minha referencia de compraProduto para o produto.

<p:outputLabel value="Produto: " for="produto" />
                    <p:selectOneMenu id="produto"
                        value="#{compraBean.compraProduto.produto}"
                        converter="produtoConverter" required="true">
                        <f:selectItem itemValue="" itemLabel="Selecione..." />
                        <f:selectItems value="#{compraBean.listaProdutos}" var="produto"
                            itemValue="#{produto}" itemLabel="#{produto.nome}" />
                        <p:ajax listener="#{compraBean.carregarProduto(produto)}"
                            update="precoUnitario :formularioItens" />
                    </p:selectOneMenu>

Será que não to persistindo a lista de produtos na hora de salvar?

Está correto dessa maneira ou da outra maneira? :(

solução!

Opa consegui gravar a minha compra aqui, só que to com outro problema, sabe na hora de escolher o produto no xhtml? Então eu vo la e o primeiro produto eu escolho e fica tudo certo por exemplo, tenho produto de teste, vo la escolho esse produto e clico no inserir para mim escolher outro produto, ai clico no produto radio que tenho, e o produto de teste troca o nome para radio e os campos ficam todos iguais, oque fazer?

insira seu código aqui

public void adicionarProduto() {
        Double aux = 0.0;
        compraProdutos.add(compraProduto);
        for (Compra_produto p : compraProdutos) {
            compra.setValor(p.getProduto().getPreco() * p.getQuantidade());
            aux += p.getProduto().getPreco() * p.getQuantidade();
            compra.setPrecoTotal(aux);
        }
        System.out.println(aux);
    }

Antes ttava assim mais tava me retornando erro de nullpointer.

public void adicionarProduto() {
        Double aux = 0.0;
        compraProdutos.add(compraProduto);
        for (Compra_produto p : compraProdutos) {
            compra.setValor(p.getProduto().getPreco() * p.getQuantidade());
            aux += p.getProduto().getPreco() * p.getQuantidade();
            compra.setPrecoTotal(aux);
            compraProduto = new Compra_Produto(); // aqui me retornava o erro
        }
        System.out.println(aux);
    }