terça-feira, 21 de setembro de 2010

Palhaçada da Dell

Com a abertura do curso em São José dos Campos, estava procurando notes pela internet. Na empresa em que trabalho compraram vários Dell, e também por falar bem da Assistência Técnica, decidi por procurar seus computadores.
O Vostro e Inspiron possuem valores muito bons, mas quando vc vai fechar o negócio, percebe que o valor do frete é de R$ 140,00 por máquina.
Ligo então na Dell para ver se conseguiria algum desconto, ou que pelo menos os R$ 140,00 fossem cobrados apenas uma vez, em vez de ser cobrado de todos os 3 computadores que eu iria comprar. Eis que a atendente me faz uma comparação esdruxula: “Se vc tem doi filhos e paga uma van escolar, eles pagam pelo lugar que ocupam, não vão pagar uma vaga só, a mesma coisa ocorre com os computadores. Além disso, não posso dar mais desconto nem que você pague a vista pois o preço já é de promoção, praticamente preço de custo”. A única coisa que quem inventou um argumento desse não contava é que os consumidores não possuem um cérebro tão “evoluido” para assimilar tamanha inteligência.
Vamos a alguns fatos:
  1.  Todo processo de entrega é, na imensa maioria das vezes, subutilizado. Ou seja, sempre vai ter lugar sobrando no caminhão, kombi e etc. O que se faz é otimizar as entregas que se tem, de forma a cortar custos. Nem a UPS, que só trabalha com entregas, consegue otimizar ao máximo suas entregas. Compre livros na Amazon e vc vai ver que o frete não é proporcional por livro. Lógico que se vc pedir uma montanha deles, o frete sobe, mas o frete de um ou 10 simplesmente não varia.
  2. Colocar um preço com esse enorme frete (mais de 10%) é, na minha opinião, propaganda enganosa. Você entra num site como Buscapé para comparar preços e aparece o da Dell em primeiro, categorizado por menor preço. Aí quando vc vai comprar, o note que estava R$ 1.298 passa para R$ 1.438.  Já pensou se a moda pega? Você entra no Buscapé,  acha um note pela bagatela de R$ 500,00. Quando vai fechar o negócio, descobre que o frete é de R$ 900,00! Simplesmente o site perderia toda sua utilidade devido a “esperteza” das empresas.  Se fosse possível eu buscar o note direto na fábrica, até poderiam separar o preço do produto e do frete, mas como não é o caso, o preço ao consumidor é um só. O pior é eu ter que configurar todo o note para só ao final me aprensetarem o valor do frete. Porque já não pedem o endereço logo no começo do processo e me informam o valor do frete? Será que é medo de eu nem continuar a configuração? Por que me fazer perder tempo, já que um consumidor mais consciente não aceitaria um abuso desse, e no mínimo, buscaria por outros computadores, já computando o abusivo frete no preço dos computadores.
  3. Os cartões cobram cerca de 3% das empresas. Então se vc vai pagar pelo boleto, no mínimo 3% tem que ser dado de desconto. Além disso, se o preço a vista, em cash não tem desconto, compensa pagar parcelado e investir seu dinheiro, nem que seja na poupança. E essa história de promoção a quase preço de custo é uma história para boi dormir tão velha, que prefiro nem comentar.

Enfim, vou comprar notes em uma loja pequena mesmo, pois lá consigo negociar. Aliás, é esse poder de barganha e respeito ao cliente que torna o pequenos negócios mais competitivos. Pretendo renovar cerca de 10 notes a cada dois anos, e se isso não é nada para Dell, tenho certeza que para uma empresa menor é.
Por fim, transparência não parece ser um dos principais valores da Dell nessa questão de frete. Seria bom haver um pouco mais de respeito à inteligência do consumidor. Quando virem o preço de um computador Dell, já adicione R$ 140,00, no mínimo, ao preço
 Tive um Acer que nunca deu problema e a Assitência Técnica também foi muito boa com o Acer de um amigo. Segue uma loja onde os preços são bem em conta e onde se pode negociar: http://www.netserv19.com/ecommerce_site/index.php?&cdgc=jfjhae00/Uc&zt=1.
Abraços a todos.

sexta-feira, 17 de setembro de 2010

Validação de CPF e CNPJ em Flex

A classe Validator é feita para validar campos em Flex. Apesar de existir vários validadores por padrão, como de cartão de crédito e mail, não existem os de CPF e CNPJ. Fiz um validador para as duas, ambas com teste unitário:

 CNPJ:


package br.com.nuccitelli.validator {
     import mx.utils.ObjectUtil;
     import mx.validators.ValidationResult;
     import mx.validators.Validator;

     public class CNPJValidator extends Validator {
         static protected const FIRST_VERIFIER_DIGITS:Array=[ 5,4,3,2,9,8,7,6,5,4,3,2 ];
         static protected const SECOND_VERIFIER_DIGITS:Array=[ 6,5,4,3,2,9,8,7,6,5,4,3 ];

         override protected function doValidation(value:Object):Array {
              var results:Array=[];
              // Call base class doValidation().
              results=super.doValidation(value);
              // Return if there are errors.
              if(results.length>0)
                   return results;
              // Check first name field.
              var cnpj:String=value as String;
              if(cnpj==null||cnpj=="") {
                   return results;
              } else if(cnpj.length!=14) {
                   results.push(new ValidationResult(true,"","","O CNPJ deve conter 14 dígitos"));
                   return results;
              } else if(!verifyDigits(cnpj)) {
                   results.push(new ValidationResult(true,"","","CNPJ inválido"));
                   return results;
              }
              return results;
         }

         private function verifyDigits(cnpj:String):Boolean {
              var firstDigit:int=defineDigitValue(getDigitsPlusOperation(cnpj,FIRST_VERIFIER_DIGITS)%11);
              if(new Number(firstDigit)!=new Number(cnpj.charAt(12))) {
                   return false;
              }
              var secondDigit:int=defineDigitValue((getDigitsPlusOperation(cnpj,SECOND_VERIFIER_DIGITS)+firstDigit*2)%11);
              return new Number(secondDigit)==new Number(cnpj.charAt(13));
         }

         private function defineDigitValue(digit:int):int {
              return digit>1?11-digit:0;
         }

         private function getDigitsPlusOperation(cnpj:String,verifierDigitis:Array):int {
              var s:int=0;
              for(var i:int=0;i<12;++i) {
                   s+=new Number(cnpj.charAt(i))*verifierDigitis[i];
              }
              return s;
         }
     }
}

Teste do CNPJ:

package br.com.nuccitelli.validator {
     import flexunit.framework.Assert;
     import mx.validators.ValidationResult;

     public class CNPJValidatorTest {
         protected var cnpjValidator:CNPJValidator=new CNPJValidator();

         [Test]
         public function testValidCNPJ():void {
              Assert.assertNull(cnpjValidator.validate("11222333000181").results);
         }

         [Test]
         public function testUncompleteCNPJ():void {
              Assert.assertEquals("O CNPJ deve conter 14 dígitos",getValidationMessage(cnpjValidator.validate("1").results[0] as ValidationResult));
              Assert.assertEquals("O CNPJ deve conter 14 dígitos",getValidationMessage(cnpjValidator.validate("1212").results[0] as ValidationResult));
              Assert.assertEquals("O CNPJ deve conter 14 dígitos",getValidationMessage(cnpjValidator.validate("1122233300018").results[0] as ValidationResult));
         }

         [Test]
         public function testWrongFinalDigits():void {
              Assert.assertEquals("CNPJ inválido",getValidationMessage(cnpjValidator.validate("11222333000180").results[0] as ValidationResult));
              Assert.assertEquals("CNPJ inválido",getValidationMessage(cnpjValidator.validate("11222333000191").results[0] as ValidationResult));
              Assert.assertEquals("CNPJ inválido",getValidationMessage(cnpjValidator.validate("11222333000190").results[0] as ValidationResult));
         }

         private function getValidationMessage(result:ValidationResult):String {
              return result.errorMessage;
         }
     }
}


CPF:

package br.com.nuccitelli.validator {
     import mx.utils.ObjectUtil;
     import mx.validators.ValidationResult;
     import mx.validators.Validator;

     public class CPFValidator extends Validator {
         override protected function doValidation(value:Object):Array {
              var results:Array=[];
              // Call base class doValidation().
              results=super.doValidation(value);
              // Return if there are errors.
              if(results.length>0)
                   return results;
              // Check first name field.
              var cpf:String=value as String;
              if(cpf==null||cpf=="") {
                   return results;
              } else if(cpf.length!=11) {
                   results.push(new ValidationResult(true,"","","O CPF deve conter 11 dígitos"));
                   return results;
              } else if(!verifyDigits(cpf)) {
                   results.push(new ValidationResult(true,"","","CPF inválido"));
                   return results;
              }
              return results;
         }

         private function verifyDigits(cpf:String):Boolean {
              var firstDigit:int=defineDigitValue(getDigitsPlusOperation(cpf,10)%11);
              if(new Number(firstDigit)!=new Number(cpf.charAt(9))) {
                   return false;
              }
              var secondDigit:int=defineDigitValue((getDigitsPlusOperation(cpf,11)+firstDigit*2)%11);
              return new Number(secondDigit)==new Number(cpf.charAt(10));
         }

         private function defineDigitValue(digit:int):int {
              return digit>1?11-digit:0;
         }

         private function getDigitsPlusOperation(cpf:String,initialFactor:int):int {
              var s:int=0;
              for(var i:int=0;i<9;++i,--initialFactor) {
                   s+=new Number(cpf.charAt(i))*initialFactor;
              }
              return s;
         }
     }
}


Teste do CPF:

package br.com.nuccitelli.validator {
     import flexunit.framework.Assert;
     import mx.validators.ValidationResult;

     public class CPFValidatorTest {
         protected var cpfValidator:CPFValidator=new CPFValidator();

         [Test]
         public function testValidCPF():void {
              Assert.assertNull(cpfValidator.validate("12345678909").results);
         }

         [Test]
         public function testUncompleteCPF():void {
              Assert.assertEquals("O CPF deve conter 11 dígitos",getValidationMessage(cpfValidator.validate("1").results[0] as ValidationResult));
              Assert.assertEquals("O CPF deve conter 11 dígitos",getValidationMessage(cpfValidator.validate("1212").results[0] as ValidationResult));
              Assert.assertEquals("O CPF deve conter 11 dígitos",getValidationMessage(cpfValidator.validate("1234567890").results[0] as ValidationResult));
         }

         [Test]
         public function testWrongFinalDigits():void {
              Assert.assertEquals("CPF inválido",getValidationMessage(cpfValidator.validate("12345678919").results[0] as ValidationResult));
              Assert.assertEquals("CPF inválido",getValidationMessage(cpfValidator.validate("12345678908").results[0] as ValidationResult));
              Assert.assertEquals("CPF inválido",getValidationMessage(cpfValidator.validate("12345678918").results[0] as ValidationResult));
         }

         private function getValidationMessage(result:ValidationResult):String {
              return result.errorMessage;
         }
     }
}



Espero que economize tempo do pessoal :)