Mascara de CEP e modulo de Matrix rate

Uma mascara de CEP é algo bem simples, e da outra cara para sua loja. Além de evitar que usuários cadastrem CEPs inexistentes. Nesse post vou mostrar como colocar a mascara de CEP e como fazer com que seu modulo de Matrix Rate não pare de funcionar.

Primeiro passo é fazer o download da Jquery (pode ser feito aqui) e o download da maskedinput que pode ser baixado aqui.

Feito isso, vamos inserir os js novos a nossa loja.
Abra o xml principal, o caminho é default/seu_tema/template/page/page.xml

E insira seu JS como o exemplo abaixo:
jquery/jquery-1.8.1.js
Faça isso para os dois JS, lembrando que é MUITO importante que o jquery seja incluído ANTES da maskedinput.

Agora vamos criar o nosso JS. Crie um arquivo com nome de zipcode.js e coloque somente o código abaixo:


jQuery(document).ready(function() {
jQuery(".validate-postode").mask("99999-999");
});

Para quem entende de Jquery, note que estamos usando “JQuery” em vez de “$”, pois, utilizando “$” irá ocorrer conflito com o prototype, que é nativo do Magento.
Caso você queira colocar mascara em outros campos, é só pegar a classe do campo que você quiser e colocar. Por ex.:

Mascara de telefone celular e CPF:

jQuery(".phone").mask("9999-9999");

jQuery(".cpf").mask("999.999.999-99");

Lembrando, que do jeito que ficar com a mascara será o formato salvo no banco de dados.

Inclua seu novo JS abaixo de todos os outros.
É muito importante seguir umao odem de importação desses javascripts criados. Primeiro seria a Jquery.js , em segundo o jquery.maskedinput.js e em terceiro o zipcode.js.

Pronto, está pronto. Todos seus campos de CEP terão a mascara.

Para quem usa o matrix Rate, vale lembrar que dessa forma você irá salvar todos os CEP´s com traço no banco de dados, o que traria problemas para o Matrix Rate.
Para solucionar este conflito basta você editar o arquivo “\app\code\community\Webshopapps\Matrixrate\Model\Mysql4\Carrier\Matrixrate.php” logo após a linha 40 que é “$postcode = $request->getDestPostcode();”.

Insira o seguinte código:

$postcode = str_replace('-','',$postcode);

Esse código serve para substituir o traço (-) por vazio e não conflitar com os calculos do Matrix Rate.

Qualquer dúvida, perguntem nos comentários! =) Espero ter ajudado.

Anúncios

localhost x servidor linux

Esse mês eu finalizei meu primeiro modulo, sem ser baseado em nenhum outro. Foi um modulo de geração de keys. Durante o mês de setembro eu vou fazer um post de criação de módulos, provavelmente ele terá mais de 1 parte, talvez 3.

Mas o post é sobre desenvolver no localhost e colocar no ar em servidor linux. Eu faço todo o meu desenvolvimento utilizando o Xamp (ou wamp) e meu sistema operacional é Windows. E quando vou subi para o servidor é linux. O que isso pode acarretar de erros?

Tive vários erros devido a essa mudança de SO, o mais critico deles foi nomenclatura de pastas. Por ex, em algum momento do meu modulo eu  dou um include, em um arquivo “media/minha_pasta/arquivo.php”. Localmente, pelo meu sistema operacional ser windows eu tenho que usar “media\\minha_pasta\\arquivo.php” Então, preste bem atenção nesses detalhes antes de subir.

Outro conflito que eu tive foi em relação a nomenclatura de pastas e classes.

Para o windows “mariana” é igual a “mariAna”, mas para o linux não é. Coloque nome de pastas sempre em letras minusculas.

No caso de classe, é um pouco mais complicado, pois não é o linux ou o windows que geram conflitos, o próprio Magento não se da muito bem com classes com letra maiúscula no meio de seu nome. Por ex.: “geracaoDeChaves” não é algo que o Magento entende perfeitamente, e pode gerar muitos conflitos durante sua aplicação. Para garantir um ótimo funcionamento ideal é que seja tudo em minusculo.

 

Dicas de Front-end para Magento!

Descobri recentemente, através do meu amigo André Gugliotti, um blog novo criado pela Vanessa Metonini focado em front end do magento. Achei super legal o blog, e é uma parte que eu não me foco muito. Então, pra quem lê meu blog, acho que ler o dela também seria um complemento muito bom.

O blog dela chama Mage Front, ela posta algumas dicas de boas práticas, explica como funciona o front end do Magento e como resolver pequenos problemas que acontecem no dia-a-dia do desenvolvimento front end do Magento.

Achei legal a ideia dela de separar os posts da mesma forma que está organizado os módulos do Magento. Isso facilita muito a busca de quem se perdeu no Magento e não sabe nem por onde começar..

O blog dela ainda está no inicio também, mas os post são bem úteis, vale a pena dar uma olhadinha sempre!

Acessando API do magento para listagem de categorias

Um dos ultimos serviços que realizei, foi criar um script de listagem das categorias existentes em uma loja. Para realizar a tarefa eu usei a API do Magento, com acesso SOAP.

A parte boa desse tipo de serviço, é que eles são práticos e não requerem login e senha do cliente (que normalmente tem receio em fornecer suas senhas). Basta que o cliente crie um usuário para você  em “Sistema” -> “Compartilhar recursos” e deêm permissão de API. Tem que criar o nível de acesso e o usuário de acesso vinculado ao nível criado.

Os códigos da API são bem simples. Confesso que quase desisti de criar esse post, por tão simples que era o código, mas eu vi tanta gente em forum perguntando, que resolvi criar! Eu gastei mais tempo fazendo a função recursiva pra ler e exibir todas as categorias em modelo de árvore, do que fazendo a conexão para API da loja magento. IMPORTANTE!!! o Soap tem que estar habilitado em AMBOS os servidores (que podem ser o mesmo, mas não era meu caso).

Essa é a UNICA chamada do meu código:

$client->call($sessionId, 'catalog_category.tree');

Nessa função, eu já estou retornando em formato de árvore todas as categorias. Acho importante eu mostrar minha função recursiva também, para exibir isso no html.

function montarArvore($item){
foreach($item as $it){
if(count($it['children'])>0){
echo "<li><span class='folder'>".$it['category_id']." - ".$it['name']."</span>\n";
echo '<ul>';
montarArvore($it['children']);
echo '</ul></li>';
} else {
echo "<li><span class='file'>".$it['category_id']." - ".$it['name']."</span></li>\n";
}
}
}

Essa função serve apara montar as categorias em listagem , mostrando ela com seus respectivos filhos.

Ela só deve ser chamada uma vez no código.

Sua chamada seria:

montarArvore($attributes['children']);

Script de exclusão de endereço de clientes

Um serviço recente que eu fiz foi excluir registros de endereço de clientes. Por que me pediram isso? Começaram a utiliar um modulo novo, onde o bairro era um campo necessário, e antes não era. Me deram a tarefa de incluir o campo bairro no cadastro do cliente. Ok, campo incluído, e agora? O que fazer com o registro dos clientes ANTERIORES a esssa exclusão?

A ideia foi excluir os endereços! Somentes os endereços de clientes criados ANTES de uma data X. (Como exemplo, colocarei 01/Jan/2012)

Pensando em facilitar meu trablho, resolvi criar um script pra isso. Faria esse exclusão utilizando a API do Magento.
Meu primeiro passo era descobrir os clientes criados antes de 01/01/2012.

Para fazer consultas no magento é usado um array como filtro.
Ex.:

$complexFilter = array(
'complex_filter' => array(
array(
'key' => 'created_at',
'value' => array('key' => 'lt', 'value' => '2012-01-01 00:01:00')
)
)
);

Nesse meu filtro, eu procuro clientes  que o campo “created_at” sejá menor que 2012/01/01 as 00:01:00.

O LT como key significa “less than" que é “menor que”

Opções existentes:

array("from"=>$fromValue, "to"=>$toValue)
array("like"=>$como)
array("neq"=>$naoIgual)
array("in"=>array($comOsValores))
array("nin"=>array($semOsValores))
array("eq"=>$igual)
array("nlike"=>$nãoComo)
array("is"=>$is )
array("gt"=>$maiorQue)
array("lt"=>$menorQue)
array("gteq"=>$MaioOuIgualQue)
array("lteq"=>$menorOuIgualQue)
array("finset"=>$unknown )

Decidido os filtros, você chama seu metodo assim:

$result = $proxy->customerCustomerList($session, $complexFilter);

No meu caso, como eu queria clientes (customer), eu chamei a customerCustomerList, mas os filtros podem ser usados para qualquer List. Clique aqui para saber sobre as funções da API.

Antes de continuar, é importante você saber que um cliente pode ter vários endereços. Isos é uma coisa que o magento permite, você ter um endereço pra cobrança, um pra entrega, e quando qiser entregar em outro endereço, você pode cadastrar outro. Então, o primeiro passo para começar a deletar os endereços é saber quais são os endereços dos clientes retornados e se eles possuem endereço.

Algum cadastros de clientes foramf eitos, mas ele ainda pode não etr efetuado nenhuma compra, e nem tenha endereço. Então, vamos fazer uma verificação apra ver se o cliente possui endereço.

try{
$adressClient = $proxy->customerAddressList($sessionId, $idClient);
}catch(exception $e) {
}

Coloquei a minha chamado de metodo dentro de um try…catch, pois, caso o id do cliente não exista  ele irá dar erro. Abaixo disso, eu fiz uma verificação se a variavel $adressClient era diferente de NULL, ou seja, se o cliente possuir endereço.

Para excluir o enderço, você irá usar o ID DO ENDEREÇO e não o ID DO CLIENTE. Atenção nisso, encontrei muitos erros relacionados a isso. Com a consulta anterior você irá obter todos os ids de endereço do cliente procurado.

O codigo terá que ficar dentro de um foreach, pois o endereço, como eu já disse, pode retornar mais de um.


foreach($adressClient as $ad){
$idAddress = $ad->customer_address_id;
$deletanteAdress = $proxy->customerAddressDelete($sessionId, $idAddress);
}

Gostei muito deste post, pois apesar de ele ser simples, tem vários itens que geram confusão. Os filtros complexo são algo com pouca documentação existente. Pude perceber nas minhas buscas pela internet, que muita pessoas utilizando o ID DO CLIENTE com as funções de endereço, e isso não funciona. O certo é usar o ID DO ENDEREÇO. Isso é muito importante, os topicos do forum mostram muitas coisas erradas em relação a isso.

Modulo de imagem no menu

Essa semana comecei a realizar meu primeiro modulo. Ainda é um modulo que mexe mais com a parte de template, mas aprendi várias coisas. Ele foi baseado em um modulo já existente de menu.

A ideia era criar um menu parecido com o das lojas americanas, com imagens.


As imagens seriam buscadas na imagem da categoria salvas no admin do magento. Elas deveriam ser de tamanho 80×40, onde a primeira (40×40) seria a imagem do menu, e a segunda seria a imagem que aparecia no mouseOver.
Além disso, teria um limite de subcategorias que aparecem, e um botão “ver +”. Clicando nesse botão o usuário iria pra uma listagem das subcategorias.
Esses eram os requisitos solicitados no modulo.

Foi bem simples de fazer, incluí a quantidade de limite de subcategoria para ser setado no admin do magento. O tamanho da div que abre no mouseOver também foi setado pelo admin do magento, pois no modulo inicial ele ocupava todo o espaço, e essa não era mais a ideia.

Na primeira versão eu me baseei muito no modulo existente, achando que ele era a programação ideal, tive que mudar isso na segunda versão.

O css e o js dele eram setados por código php, e eu passei para xml.
Separei o css somente para o menu, sem afetar os outros elementos da página.
Arrumei alguma coisa no JS, para pegar o tamanho da div do mouseOver no admin.

Acho importante contar um pouco sobre o CSS pelo xml.
Todo modulo tem um .xml na pasta layout do seu tema, no meu caso “default/default”. Para setar o css por esse arquivo, basta você criar um reference ao head (onde fica o css e js) e criar a action de adicionar ambos.

Ex.:
<block type="imagemenu/toggle">
<reference name="head">
<action method="addCss"><stylesheet>css/imagemmenu.css</stylesheet></action>
<action method="addItem"><type>skin_js</type><name>js/imagemenu.js</name><params/><if/></action>
</reference>
</block>

Colocar isso em um aquivo php não é o correto, pois você poderá ter problemas caso o seu modulo esteja em um tema do cliente, que não seja default/default
No caso do modulo que eu peguei de base, a chamada do css e do JS estava em “app/code/local/nomeGrupo/nomeModulo/Block/Toggle.php. esse é o jeito errado.

$layout = $this->getLayout();
$head = $layout->getBlock('head');
$head->addItem('skin_js', 'js/md/imagemenu/imagemenu.js');
$head->addItem('skin_css', 'css/md/custommenu/custommenu.css');

Uma coisa importante também, é como chamar um campo que foi criado no admin.
Esse foi o campo que eu criei no admin do magento:

<subcategory_max translate="label comment">
<label>Sub category in menu</label>
<comment><![CDATA[O maximo de sub categorias &eacute; referente a cada categoria do item anterior]]></comment>
<frontend_type>text</frontend_type>
<sort_order>300</sort_order>
<show_in_default>3</show_in_default>
<show_in_website>3</show_in_website>
<show_in_store>3</show_in_store>
</subcategory_max>

Para chamar ele, é usado o nome da primeira tag. Ficou assim:

$max_subcategory = (int)Mage::getStoreConfig('image_menu/general/subcategory_max');

Outra coisa interessante também, é como eu chamei a imagem da categoria. O id já era passado para o método que eu estava mexendo. Com esse id eu consigo buscar os dados da categoria.

$categoriaImg = Mage::getModel('catalog/category')->load($id);
$img = $categoriaImg->getImageUrl();

Acho que é isso..
O modulo foi implementado para um cliente especifico. Caso alguém tenha interesse em implementar esse modulo  em sua loja virtual, entre em contato comigo =)

Mostrar produtos na home

Bom, todo mundo já sabe que existem várias formas de fazer isso. Vou explica a que eu acho correta e sem chance de erros.

Quando você instala o sample data (explicação sobre isso aqui), a visão de produtos que você tem na capa é a mais errada possivel. Por que? Somente pelo fato de ela não ser nada dinâmina. Daquela forma toda vez que o cliente quiser trocar aqueles produtos ele vai ter que abrir pelo painel de administração do mangento, ir em “CMS” -> “Página” e trocar os produtos a mão, colocando a foto deles, e o link, e etc..  Ou seja, um trabalhão.

Existe ainda uma segunda forma, que eu passei a considerar ela errada, simplesmente pelo fato de ela não funcionar como eu previa. Acredito que ela funcione melhor em versões antigas (1.5 rpa traz). Tive vários problemas com ela, então, não aconselho.
É colocar esse código no “CMS”->”Pagina”->”Template”:
{{block type=”catalog/product_list” name=”home.catalog.product.list” alias=”products_homepage” category_id=”4″ template=”catalog/product/list.phtml”}}

Na teoria era pra ele funcionar corretamente, mas minha experiência não diz isso. Ocorre vários erros.
Nessa linha de código você está solicitando para listar todos os produtos da categoria de ID 4 (você pode ver o ID da categoria no gerencimento da categoria no painel administrativo). Essa listagem deve usar o html do arquivo catalog/product/list.phtml do seu template.

E existe a maneira ideal, que é através do xml.
Pode ser pelo próprio painel administrativo do magento, mas, em vez de “CMS”->”Pagina”->”Template”, você vai direto no código xml “Atualização de Layout XML”
E coloque o código:
<reference name=”content”>
<block type=”catalog/product_list” name=”featured” template=”catalog/product/list.phtml”>
<action method=”setCategoryId”><category_id>4</category_id></action>
</block>
</reference>
Esse código diz exatamente o que o código anterior diz, só que em lugares diferentes.
Aonde está “<category_id>4</category_id>” Você vai mudar o número para o teu código de categoria.
E o mesmo para o arquivo html. Aonde está “catalog/product/list.phtml” você pode colocar o caminho do seu arquivo phtml.

A vantagem dessas forma de categorias, é que o usuário pode somente acrescentar produtos novos a essa categoria escolhida e ele irá atualizar sozinho na pagina inicial.

Uma coisa que eu descobri também, é que o Magento pode ter categorias “fantasma”. O que isso quer dizer? Você cria uma categoria, e associa produtos aquela categoria. Quando você excluir a categoria essa associação não é perdida. OU seja, se você listar produtos de uma categoria que já existiu, que foi apagada, os produtos que estavam vinculadas a ela irão aparecer. Eu considero isso um defeito do magento.

Espero que tenha ajudado.