Carrinho De Compras

Alguem ja fez algum carrinho de compras com yii, que poderia compartilhar ou pelo menos dar umas dicas de como fzer de maneira bem simples. É a primeira vez que estou tentado fazer mais está muito dificil dar os primeiros passos.

Obrigada

Tem um projeto que foi baseado no Opencart que acho que pode te ajudar.

Wanderson eu achei muito interessante este projeto… so que vc já fez o teste com ele? vc ja aplicou em algum projeto? Tem a tradução para portugues?

Valew

Ana eu utilizei sessão como segue abaixo:

CarrinhoController.php


public function actionIndex()

	{

            

            

            if(isset($_POST['add'])){

                $produto = Produto::model()->findByPk($_POST['add']['id']);

                $quantidade = $_POST['add']['qtde'];

                if($produto->estoque <= 0):

                      Yii::app()->user->setFlash('error','Desculpe, mas não possuimos estoque do item '.$produto->nome.'');

                     $quantidade = $produto->estoque;

                else:

                    if($quantidade > $produto->estoque):

                        Yii::app()->user->setFlash('error','Desculpe, mas só é possível comprar até '.$produto->estoque.' unidades do item '.$produto->nome.'');

                        $quantidade = $produto->estoque;

                        Cesta::adicionar($_POST['add']['id'],$quantidade);

                    else:

                        if($produto->estoque == 0):

                            Yii::app()->user->setFlash('error','Desculpe, mas não possuimos estoque do item '.$produto->nome.'');

                        else:

                            Cesta::adicionar($_POST['add']['id'],$quantidade);

                        endif;

                    endif;

                endif;

            

            }

            if(Yii::app()->request->isAjaxRequest){

                if(isset($_POST['excluir'])){

                    Cesta::excluir($_POST['excluir']);

                }

                if(isset($_POST['carrinho'])){

                    foreach ($_POST['carrinho'] as $id => $qtde){

                        $produto = Produto::model()->findByPk($id);

                        $quantidade = $qtde;

                        if($quantidade > $produto->estoque):

                            $quantidade = $produto->estoque;                       

                            Cesta::alterar($id, $quantidade);

                          

                         else:

                             Cesta::alterar($id, $quantidade);

                         endif;                  

                        

                        

                    }

                    Cesta::frete($_POST['txtcep'],$_POST['TipoFrete']);                 

                    

                }   

                

                

               

                $this->renderPartial('_carrinho', array('carrinho'=>Cesta::listarCarrinho()), false, false);

            }else{

                  

                 $this->render('index', array('carrinho'=>Cesta::listarCarrinho()));

            }

            

	}

        

              

        

        public function actionCalcularfrete(){

            $cep = $_POST['txtcep'];

            $validaCEP = "http://cep.republicavirtual.com.br/web_cep.php?cep=".$cep."&formato=xml";        

            $xml = @simplexml_load_file($validaCEP);   

            if($xml->resultado == 0){

                echo "<span class='hint label label-warning'>

                          Cep não encontrado, verifique o CEP digitado.

                      </span>";

               

            }else{

                $kilo = Cesta::calcularKilo();

                $valorDeclarado = Cesta::valorTotal();

                $fretePAC = Cesta::calculaFrete('41106','17506-040',$cep,$kilo);

                $freteSEDEX = Cesta::calculaFrete('40010','17506-040',$cep,$kilo);

                echo CHtml::radioButtonList('TipoFrete','',array('PAC'=>'PAC - Prazo estimado de '.$fretePAC->PrazoEntrega.' dias úteis - <span class="price">R$ '.$fretePAC->Valor.'</span>',

                                                                    'SEDEX'=>'SEDEX - Prazo estimado de '.$freteSEDEX->PrazoEntrega.' dias úteis - <span class="price">R$ '.$freteSEDEX->Valor.'</span>'),

                                                    array('separator'=>false))."<div class='clearfix'></div>"; 

                

            }


            

        }

Components/Cesta.php


class Cesta {

    

    public function __construct() {

        if(!isset($_SESSION['cestadecompra'])){

            $_SESSION['cestadecompra'] = array();

        }

    }

    

    public function adicionar($id, $qtde = 1){

        $produto = Produto::model()->findByPk($id);

        

        session_start();

        $id = (int)$id;

        $qtde = (int)$qtde;

        $qtde = (empty($qtde) || $qtde == 0) ? 1 : $qtde;

        

        if(isset($_SESSION['cestadecompra']['produto'][$id])){

            $_SESSION['cestadecompra']['produto'][$id] += 1;

            if($_SESSION['cestadecompra']['produto'][$id] > $produto->estoque):

                $_SESSION['cestadecompra']['produto'][$id] = $produto->estoque; 

            endif;           

        }else{

            $_SESSION['cestadecompra']['produto'][$id] = $qtde;          

        }

    }

    

    

    public function verificaCarrinho(){

        session_start();

        if(isset($_SESSION['cestadecompra'])){

            if(sizeof($_SESSION['cestadecompra'])>0){

                return true;

            }else{

                return false;

            }            

        }else{

            return false;

        }

        

        

    }




    public function alterar($id, $qtde){

        $produto = Produto::model()->findByPk($id); 

        session_start();

        $id = (int)$id;

        $qtde = (int)$qtde;

        $qtde = (empty($qtde) || $qtde == 0) ? 1 : $qtde;

        if(isset($_SESSION['cestadecompra']['produto'][$id])){

            $_SESSION['cestadecompra']['produto'][$id] = $qtde;

            if($_SESSION['cestadecompra']['produto'][$id] > $produto->estoque):

                $_SESSION['cestadecompra']['produto'][$id] = $produto->estoque; 

            endif;  

        }

    }

    

    public function excluir($id){

        session_start();

        unset($_SESSION['cestadecompra']['produto'][$id]);

    }

    

    public function listarProdutos(){

        session_start();

        $result = array();

        if(sizeof($_SESSION['cestadecompra']['produto']) >0 ){

            foreach($_SESSION['cestadecompra']['produto'] as $id => $qtde){

                $prod = Produto::model()->findByPk($id);

                $result[$id]['id'] = $prod->id;

                $result[$id]['parent'] = $prod->categorias->parent;

                $result[$id]['idcategoria'] = $prod->idcategoria;

                $result[$id]['nomecategoria'] = $prod->categorias->nome;

                $result[$id]['foto'] = $prod->fotoprodutos[0]->arquivo;

                $result[$id]['nome'] = $prod->nome;

                $result[$id]['preco'] = $prod->precovenda;

                $result[$id]['peso'] = $prod->peso * $qtde;

                $result[$id]['qtde'] = $qtde;

                $result[$id]['codigo'] = str_pad($prod->codigo, 10, "0", STR_PAD_LEFT);

                $result[$id]['subtotal'] = $prod->precovenda * $qtde;

            }

        }

        return $result;

    }

    

    public function listarCarrinhoWidget(){

        

        $geral = array();

        $geral['carrinho'] = self::listarProdutos();

        $geral['total'] = self::valorTotal(); 

        return $geral;

        

    }

    

    public function listarCarrinho(){

        

        $frete = self::frete();

        $valorFrete = $frete['valorFrete'];

        $valorFrete = str_replace(',','.',str_replace('.','',$valorFrete));

        $geral = array();

        $geral['carrinho'] = self::listarProdutos();

        $geral['total'] = self::valorTotal(); 

        $geral['totalGeral'] = self::valorTotal() + $valorFrete;

        $geral['frete'] = self::frete();

        return $geral;

        

    }

    

    public function frete($cep = '', $tipo = ''){

        session_start();

        $cepRow = array();

        if(!(empty($cep) && empty($tipo))){

            $_SESSION['frete']['tipo'] = $tipo;

            $_SESSION['frete']['cep'] = $cep;

            $kilo = self::calcularKilo();

            $valorDeclarado = number_format(self::valorTotal(),2,",",".");

            $fretePAC = Cesta::calculaFrete('41106','17506-040',$cep,$kilo, $valorDeclarado);

            $freteSEDEX = Cesta::calculaFrete('40010','17506-040',$cep,$kilo, $valorDeclarado);

            $cepRow['conteudo'] =  CHtml::radioButtonList('TipoFrete','',array('PAC'=>'PAC - Prazo estimado de '.$fretePAC->PrazoEntrega.' dias úteis - <span class="price">R$ '.$fretePAC->Valor.'</span>',

                                                                    'SEDEX'=>'SEDEX - Prazo estimado de '.$freteSEDEX->PrazoEntrega.' dias úteis - <span class="price">R$ '.$freteSEDEX->Valor.'</span>'),

                                                    array('separator'=>false))."<div class='clearfix'></div>"; 

            

            $cepRow['conteudo'] .= '<input type="hidden" name="valorPAC" value="'.$fretePAC->Valor.'" />';

            $cepRow['conteudo'] .= '<input type="hidden" name="valorSEDEX" value="'.$freteSEDEX->Valor.'" />';

            

            $cepRow['cep'] = $cep;

            $cepRow['tipo'] = $tipo;

            return $cepRow;

        }elseif($_SESSION['frete']['tipo'] != '' && $_SESSION['frete']['cep'] != ''){

            $kilo = self::calcularKilo();

            $valorDeclarado = number_format(self::valorTotal(),2,",",".");

            $fretePAC = Cesta::calculaFrete('41106','17506-040',$_SESSION['frete']['cep'],$kilo, $valorDeclarado);

            $freteSEDEX = Cesta::calculaFrete('40010','17506-040',$_SESSION['frete']['cep'],$kilo, $valorDeclarado);

            $cepRow['conteudo'] = CHtml::radioButtonList('TipoFrete',$_SESSION['frete']['tipo'],array('PAC'=>'PAC - Prazo estimado de '.$fretePAC->PrazoEntrega.' dias úteis - <span class="price">R$ '.$fretePAC->Valor.'</span>',

                                                                    'SEDEX'=>'SEDEX - Prazo estimado de '.$freteSEDEX->PrazoEntrega.' dias úteis - <span class="price">R$ '.$freteSEDEX->Valor.'</span>'),

                                                    array('separator'=>false))."<div class='clearfix'></div>"; 

            if($_SESSION['frete']['tipo'] == 'PAC'){

                $cepRow['valorFrete'] = $fretePAC->Valor;

            }else{

                $cepRow['valorFrete'] = $freteSEDEX->Valor;

            }

             

            $cepRow['cep'] = $_SESSION['frete']['cep'];

            $cepRow['tipo'] = $_SESSION['frete']['tipo'];

            return $cepRow;

        }

        

    }

    

    public function valorTotal(){

        $produto = self::listarProdutos();

        $total = 0;

        foreach ($produto as $id => $row){

            $total += $row['subtotal'];

        }

        return $total;

    }

    

    public function calcularKilo(){

        $peso = self::listarProdutos();

        $total = 0;

        foreach ($peso as $id => $row){

            $total += $row['peso'];

        }

        return $total/1000;

    }

    

   

    

    public function calculaFrete($servico, $CEPorigem, $CEPdestino, $peso, $valor='1.00', $altura='4', $largura='12', $comprimento='16'){

        ////////////////////////////////////////////////

        // Código dos Serviços dos Correios

        // 41106 PAC

        // 40010 SEDEX

        // 40045 SEDEX a Cobrar

        // 40215 SEDEX 10

        ////////////////////////////////////////////////

        // URL do WebService        

        $correios = "http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=".$CEPorigem."&sCepDestino=".$CEPdestino."&nVlPeso=".$peso."&nCdFormato=1&nVlComprimento=".$comprimento."&nVlAltura=".$altura."&nVlLargura=".$largura."&sCdMaoPropria=n&nVlValorDeclarado=".$valor."&sCdAvisoRecebimento=n&nCdServico=".$servico."&nVlDiametro=0&StrRetorno=xml";

        // Carrega o XML de Retorno

        $xml = @simplexml_load_file($correios);

        // Verifica se não há erros

        if($xml->cServico->Erro == '0'){

            return $xml->cServico;

        }else{

            return false;

        }

    }

    

}

Obrigada Edson e Wanderson vou testar depois se tiver alguma dúvida digo-vos…

Ola Edson Rodrigues, eu não percebi porque é que criaste os métodos add, excluir e listar no components/cesta.php e nao no carrinhoController.php…Tem alguma razão para isso??

Obrigada e agradeço a resposta desde já…

Ola Ana, como vc pode ver esta são as acoes do usuário, quando ele clica em comprar é submetido o id do produto e a quantidade selecionada. Está é a funcão do Add que por sua vez chama o método cesta::adicionar(), quando ele acessa o carrinho de compra ele tem a opçao de excluir o produto do carrinho, quando ele clica no botao excluir ele chama o metodo cesta::excluir, sobre o metodo lista ele retorna o array para que eu possa montar a tabela com os produtos do carrinho.

Esta é apenas uma ideia caso queira melhorar pode melhorar…sucesso!!!

Obrigada mais uma vez Edson pela explicação…

Segue o render do Carrinho, talvez ajude!!!


<?php 

    if(sizeof($carrinho['carrinho']) == 0 ):

?>

<br /><br />


<h4 class="titulo-carrinho">Não há produtos em seu carrinho.</h4>


<p>Para inserir produtos no seu carrinho, navegue pelos departamentos ou utilize a busca do site. Ao encontrar os itens desejados, clique no botão Comprar.</p>

<br /><a href="/" class="btn floatLeft"><i class="icon-chevron-left"></i> Voltar para a loja</a>


<?php

    else:

?>

<?php echo CHtml::beginForm('','post',array('class'=>'form-inline')); ?>

 

     <div class="btncarrinho">

        <a href="/" class="btn floatLeft"><i class="icon-chevron-left"></i> Comprar mais produto</a>

        <a href="/carrinho/finalizarcompra" class="btn floatRightbtn btn-primary"><i class="icon-ok icon-white"></i> Finalizar Compra</a>

         <?php

            echo CHtml::ajaxLink(

            '<i class="icon-refresh"></i> Atualizar Valores', array('carrinho/index'), 

                array('type' => 'POST',

                       'update'=>'#carrinho-compras'

                    ),

                array('href' => Yii::app()->createUrl('carrinho/index'),

                      'class' => 'btn floatRightbtn'

                )

            );

        ?>

    </div>

    <div class="clearfix"></div>

    <table border="0" class="table table-striped table-condensed">

        <thead>

            <tr>

                <th class="text-left" width="500">Produtos</th>

                <th>Excluir</th>

                <th>Quantidade</th>

                <th>Preço Unitário</th>

                <th width="100">Preço Total</th>

            </tr>

        </thead>

        <tfoot>

            <tr>

                <th colspan="4" class="line-height44">Subtotal:</th>

                <td>R$ <?php echo number_format($carrinho['total'],2,",", "."); ?></td>

               

            </tr>

            <tr>

                <td>Estimativa de Frete


Informe seu CEP para calcular o valor do frete.

                <td colspan="3">

                        <label for="txtcep">CEP.:</label>

                        <?php $this->widget('CMaskedTextField',array(

                            'name'=>'txtcep',

                            'value'=>$carrinho['frete']['cep'],

                            'mask'=>'99999-999',

                            'htmlOptions'=>array('class'=>'input-medium'),

                        )); ?>

                        <script>

                             $("#txtcep").mask("99999-999");

                        </script>

                       <a href="javascript:;" id="btncalcular" class="btn">Calcular</a>

                        <?php

                        Yii::app()->clientScript->registerScript('calcularfrete', "

                            $('#btncalcular').live('click',function(e){

                                e.preventDefault();

                                $.ajax({

                                   type:'POST',

                                   cache:false,

                                   url:'/carrinho/calcularfrete',

                                   data:{txtcep:$('#txtcep').val()},

                                   

                                   success:function(data){                                        

                                        $('#resultadofrete').html(data);

                                       

                                   }

                                    

                                })

                                

                            });                       

                        ");

                        ?>

                      

                        <div id="resultadofrete" class="controls-frete">

                            <?php echo $carrinho['frete']['conteudo']; ?>

                        </div>

                     

                       

                       

                </td>           

               

                <td><?php echo ($carrinho['frete']['valorFrete'] == '') ? 'R$ 0,00' : 'R$ '.$carrinho['frete']['valorFrete']; ?></</td>

               

            </tr>

            <tr class="carrinho-total">

                <th colspan="4" class="line-height44">Total:</th>

                <td>R$ <?php echo number_format($carrinho['totalGeral'],2,",", "."); ?></td>

               

            </tr>

       </tfoot>

        <tbody>

           <?php foreach($carrinho['carrinho'] as $cat): ?>

            <tr>

                <th width="500">

                    <?php if(empty($cat['foto'])): ?>

                        <img src="/fotos/thumbs/produto-sem-foto.jpg" width="48" height="44" alt="Nome" />

                    <?php else: ?>

                        <img src="/fotos/thumbs/<?php echo $cat['foto']; ?>" width="48" height="44" alt="Nome" />

                    <?php endif ?>

                    

                     <p>

                         <?php if($cat['parent'] == 0): ?>

                            <a href="<?php echo Yii::app()->createUrl('produtos/view',array('idloja'=>funcao::IdCategoriaPai($cat['idcategoria']),'loja'=>funcao::NomeCategoriaPai($cat['idcategoria']),'idprod'=>$cat['id'],'produto'=>funcao::slug($cat['nome']))) ?>">

                        <?php else: ?>

                            <a href="<?php echo Yii::app()->createUrl('produtos/view',array('idloja'=>funcao::IdCategoriaPai($cat['idcategoria']),'loja'=>funcao::NomeCategoriaPai($cat['idcategoria']),'idcat'=>$cat['idcategoria'],'categoria'=>funcao::slug($cat['nomecategoria']),'idprod'=>$cat['id'],'produto'=>funcao::slug($cat['nome']))) ?>">

                        <?php endif; ?>

                         <?php echo $cat['nome']; ?></a>

                        <br /><span>Cod.: <?php echo $cat['codigo']; ?></span>

                      </p>                   

                </th>

                <td>

                    <?php

                        echo CHtml::ajaxLink(

                        '<i class="icon-remove"></i>', array('carrinho/index'), 

                            array('type' => 'POST',

                                  'update'=>'#carrinho-compras',

                                  'data' => array('excluir'=>$cat['id'])

                                ),

                            array('href' => Yii::app()->createUrl('carrinho/index'),

                                 'class' => 'excluir-item',

                                 'title' => 'Excluir'

                            )

                        );

                    ?>

                  

                

                </td>

                <td><input type="text" size="3" id="txtqtdecar" class="input-mini-mini" name="carrinho[<?php echo $cat['id']; ?>]" value="<?php echo $cat['qtde']; ?>" /></td>

                <td>R$ <?php echo number_format($cat['preco'],2,",", "."); ?></td>

                <td>R$ <?php echo number_format($cat['subtotal'],2,",", "."); ?></td>

            </tr>

            <?php endforeach; ?>

       </tbody>

    </table>

    <span class="aviso hint label label-important">

        Para alterar a quantidade do(s) item(ns) acima, clique sobre a unidade e digite a quantidade desejada. Depois clique no botão <strong>"Atualizar valores"</strong>.<br />

        O quantidade máxima de cada produto sempre vai ser o limite atual do nosso estoque.

    </span>

    <div class="btncarrinho">

        <a href="/" class="btn floatLeft"><i class="icon-chevron-left"></i> Comprar mais produto</a>

        <a href="/carrinho/finalizarcompra" class="btn floatRightbtn btn-primary"><i class="icon-ok icon-white"></i> Finalizar Compra</a>

         <?php

            echo CHtml::ajaxLink(

            '<i class="icon-refresh"></i> Atualizar Valores', array('carrinho/index'), 

                array('type' => 'POST',

                       'update'=>'#carrinho-compras'

                    ),

                array('href' => Yii::app()->createUrl('carrinho/index'),

                      'class' => 'btn floatRightbtn'

                )

            );

        ?>

    </div>

 <?php echo CHtml::endForm(); ?>  

 <?php endif; ?>



Sucesso!!!

Ana,

Se quizer mais modelos de exemplos.

http://www.yiiframework.com/extension/yiishop/

Obrigada (Edson e Newerton) espero conseguir resolver isso o mais rápido possivel…

se conseguir resolver de uma forma diferente depois eu deixo aqui a minha solução