From 23ccaa46597b23bdfb0e9609592ac44a66259424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 6 Apr 2011 22:29:45 -0700 Subject: [PATCH 01/49] Modificado path al ejecutable de openssl en wsaa-client.sh. Ahora depende del path del sistema. --- wsaa-client.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 wsaa-client.sh diff --git a/wsaa-client.sh b/wsaa-client.sh old mode 100755 new mode 100644 index 76952d9..b41085c --- a/wsaa-client.sh +++ b/wsaa-client.sh @@ -46,9 +46,9 @@ function MakeCMS() { CMS=$( echo "$TRA" | - /usr/local/ssl/bin/openssl cms -sign -in /dev/stdin -signer $CRT -inkey $KEY -nodetach \ + openssl cms -sign -in /dev/stdin -signer $CRT -inkey $KEY -nodetach \ -outform der | - /usr/local/ssl/bin/openssl base64 -e + openssl base64 -e ) } #------------------------------------------------------------------------------ From f0cd76e1f82a12357f06aa64b26a72d4e8756041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 6 Apr 2011 22:30:42 -0700 Subject: [PATCH 02/49] Dependencias agregadas --- lib/bravo.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/bravo.rb b/lib/bravo.rb index a0ad78f..67f23c8 100644 --- a/lib/bravo.rb +++ b/lib/bravo.rb @@ -5,6 +5,10 @@ require "bravo/core_ext/float" require "bravo/core_ext/hash" require "bravo/core_ext/string" + +require 'net/http' +require 'net/https' + module Bravo class NullOrInvalidAttribute < StandardError; end From f50409b3df599cbfbac24e6e3ebacfc0ce9c91da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 6 Apr 2011 23:03:02 -0700 Subject: [PATCH 03/49] Corregido rechazo de comprobantes de "Productos" --- lib/bravo/bill.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 40e0920..03dc057 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -88,7 +88,7 @@ def setup_bill detail["ImpTotal"] = total detail["CbteDesde"] = detail["CbteHasta"] = next_bill_number - unless concepto == 0 + unless concepto == "Productos" # En "Productos" ("01"), si se mandan estos parámetros la afip rechaza. detail.merge!({"FchServDesde" => fch_serv_desde || today, "FchServHasta" => fch_serv_hasta || today, "FchVtoPago" => due_date || today}) From 054e4758dde1c915839cc1089b5f606eee3b9103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 6 Apr 2011 23:08:35 -0700 Subject: [PATCH 04/49] =?UTF-8?q?Agregada=20informaci=C3=B3n=20de=20instal?= =?UTF-8?q?aci=C3=B3n=20de=20openssl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.textile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.textile b/README.textile index 53385a1..dd5d212 100644 --- a/README.textile +++ b/README.textile @@ -16,6 +16,24 @@ o en tu @Gemfile@ +Nota: Para que funcione el proceso de autenticación WSAA, chequear si el openssl instalado tiene compilado el módulo "cms" : +
+openssl cms
+
+ +Si no dice "Invalid command", estamos bien. Caso contrario, descargar openssl y compilarlo con: +
+./configure enable-cms
+make
+make install
+
+ +Nota 2: Ojo! Probablemente el openssl instalado originalmente sea el que se acceda por el path. Normalmente esto lo soluciona: + +
+whereis openssl
+ln -s /usr/local/ssl/bin/openssl RUTA_OBTENIDA_DEL_COMANDO_ANTERIOR
+
h2. Configuración From 1f55ce68f74be43e7c47f38a7821589e04b66d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Thu, 7 Apr 2011 10:14:02 -0700 Subject: [PATCH 05/49] Nota sobre incompatibilidad Windows --- README.textile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.textile b/README.textile index dd5d212..fdfe606 100644 --- a/README.textile +++ b/README.textile @@ -17,21 +17,17 @@ o en tu @Gemfile@ Nota: Para que funcione el proceso de autenticación WSAA, chequear si el openssl instalado tiene compilado el módulo "cms" : -
-openssl cms
-
+
openssl cms
Si no dice "Invalid command", estamos bien. Caso contrario, descargar openssl y compilarlo con: -
-./configure enable-cms
+
./configure enable-cms
 make
 make install
 
Nota 2: Ojo! Probablemente el openssl instalado originalmente sea el que se acceda por el path. Normalmente esto lo soluciona: -
-whereis openssl
+
whereis openssl
 ln -s /usr/local/ssl/bin/openssl RUTA_OBTENIDA_DEL_COMANDO_ANTERIOR
 
@@ -39,6 +35,8 @@ h2. Configuración Los servicios de AFIP requieren la utilización del Web Service de Autorización y Autenticación ("wsaa readme":http://www.afip.gov.ar/ws/WSAA/README.txt) +Nota: El proceso de WSAA en Bravo está implementado con un script Bash. Esto es incompatible con un servidor Windows. + Luego de cumplidos los pasos indicados en el readme, basta con configurar Bravo con la ruta a los archivos:

From 4b96d698fa3cd5ea131bd0180a8c491cb407678b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 12:02:37 -0700
Subject: [PATCH 06/49] =?UTF-8?q?Agregu=C3=A9=20archivo=20de=20salida=20pa?=
 =?UTF-8?q?rametrizable?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 wsaa-client.sh | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/wsaa-client.sh b/wsaa-client.sh
index b41085c..0a2cc79 100644
--- a/wsaa-client.sh
+++ b/wsaa-client.sh
@@ -132,7 +132,7 @@ EOF
 
 function WriteYAML()
 {
-	cat < /tmp/bravo_$(date +"%d_%m_%Y").yml
+	cat < $DATAFILE
 token: '$TOKEN'
 sign: '$SIGN'
 EOF
@@ -147,7 +147,7 @@ EOF
 #[ $# -eq 0 ] && read -p "Service name: " SERVICE
 
 # Parse commandline arguments
-while getopts 'k:u:c:' OPTION
+while getopts 'k:u:c:a:' OPTION
 do
     case $OPTION in
     c)    CRT=$OPTARG
@@ -155,9 +155,13 @@ do
     k)    KEY=$OPTARG
         ;;
     u)    URL=$OPTARG
+        ;;             
+    a)    DATAFILE=$OPTARG
         ;;
     esac
-done
+done             
+echo "Using output file $DATAFILE"
+
 shift $(($OPTIND - 1))
 MakeTRA          # Generate TRA
 MakeCMS          # Generate CMS (TRA + signature + certificate)

From df363d2cf2b47207d18d67d97f0ebdb5c3493483 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 12:03:52 -0700
Subject: [PATCH 07/49] =?UTF-8?q?Mov=C3=AD=20archivo=20de=20salida=20de=20?=
 =?UTF-8?q?WSAA=20a=20directorio=20tmp=20dentro=20del=20proyecto=20(para?=
 =?UTF-8?q?=20soportar=20varias=20apps=20que=20usen=20Bravo=20en=20el=20mi?=
 =?UTF-8?q?smo=20host)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/auth_data.rb | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb
index 1b10f8e..b668825 100644
--- a/lib/bravo/auth_data.rb
+++ b/lib/bravo/auth_data.rb
@@ -11,10 +11,12 @@ def fetch
           raise "Archivo certificado no encontrado en #{Bravo.cert}"
         end
 
-        todays_datafile = "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
+        #todays_datafile = "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
+        todays_datafile = Dir.pwd + "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
         opts = "-u #{Bravo.auth_url}"
         opts += " -k #{Bravo.pkey}"
-        opts += " -c #{Bravo.cert}"
+        opts += " -c #{Bravo.cert}" 
+        opts += " -a #{todays_datafile}"         
 
         unless File.exists?(todays_datafile)
           %x(#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts})

From 55ebaad3b54cffdc653d0be1bf661da938165391 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 12:10:50 -0700
Subject: [PATCH 08/49] =?UTF-8?q?Agregu=C3=A9=20soporte=20a=20distintos=20?=
 =?UTF-8?q?CUIT=20en=20la=20misma=20aplicaci=C3=B3n=20(Varios=20archivos?=
 =?UTF-8?q?=20de=20salida=20de=20WSAA)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/auth_data.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb
index b668825..e6c3681 100644
--- a/lib/bravo/auth_data.rb
+++ b/lib/bravo/auth_data.rb
@@ -12,7 +12,7 @@ def fetch
         end
 
         #todays_datafile = "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
-        todays_datafile = Dir.pwd + "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml"
+        todays_datafile = Dir.pwd + "/tmp/bravo_#{Bravo.cuit}_#{Time.new.strftime('%d_%m_%Y')}.yml"
         opts = "-u #{Bravo.auth_url}"
         opts += " -k #{Bravo.pkey}"
         opts += " -c #{Bravo.cert}" 

From 3e96c1e610146e8b8540e55c5c40595b282a497e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 12:16:58 -0700
Subject: [PATCH 09/49] Parsing de "Observaciones" del rechazo de pedido de
 WSFE

---
 lib/bravo/bill.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index 03dc057..ba0f601 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -143,7 +143,8 @@ def setup_response(response)
                        :moneda        => request_detail.delete(:mon_id),
                        :cotizacion    => request_detail.delete(:mon_cotiz),
                        :iva_base_imp  => request_detail.delete(:base_imp),
-                       :doc_num       => request_detail.delete(:doc_nro)
+                       :doc_num       => request_detail.delete(:doc_nro),
+                       :observaciones => response_detail.delete(:observaciones) 
                        }.merge!(request_header).merge!(request_detail)
 
       keys, values  = response_hash.to_a.transpose

From 8de5e84890e74af6837cf295191d05e1eb1730b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 13:29:43 -0700
Subject: [PATCH 10/49] =?UTF-8?q?Parsing=20de=20"Errores"=20del=20rechazo?=
 =?UTF-8?q?=20de=20pedido=20de=20WSFE=20Falta=20soporte=20para=20m=C3=BAti?=
 =?UTF-8?q?ples=20errores/observaciones?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/bill.rb | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index ba0f601..ab1a5dd 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -131,7 +131,12 @@ def setup_response(response)
 
       iva             = request_detail.delete(:iva)["AlicIva"].underscore_keys.symbolize_keys
 
-      request_detail.merge!(iva)
+      request_detail.merge!(iva) 
+         
+      if result[:errors] then
+          response_detail.merge!( result[:errors] )     
+      end
+      
 
       response_hash = {:header_result => response_header.delete(:resultado),
                        :authorized_on => response_header.delete(:fch_proceso),
@@ -143,8 +148,9 @@ def setup_response(response)
                        :moneda        => request_detail.delete(:mon_id),
                        :cotizacion    => request_detail.delete(:mon_cotiz),
                        :iva_base_imp  => request_detail.delete(:base_imp),
-                       :doc_num       => request_detail.delete(:doc_nro),
-                       :observaciones => response_detail.delete(:observaciones) 
+                       :doc_num       => request_detail.delete(:doc_nro), 
+                       :observaciones => response_detail.delete(:observaciones),
+                       :errores       => response_detail.delete(:err) 
                        }.merge!(request_header).merge!(request_detail)
 
       keys, values  = response_hash.to_a.transpose

From b87ec0e2b77a05ee14a58fcfa0c55e0be34637b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sat, 9 Apr 2011 14:42:08 -0700
Subject: [PATCH 11/49] =?UTF-8?q?Agregu=C3=A9=20BILL=5FTYPE=20nota=20de=20?=
 =?UTF-8?q?d=C3=A9bito=20A=20y=20B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/constants.rb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/bravo/constants.rb b/lib/bravo/constants.rb
index 27f11c9..8208980 100644
--- a/lib/bravo/constants.rb
+++ b/lib/bravo/constants.rb
@@ -42,7 +42,9 @@ module Bravo
       :exento => "06",
       :responsable_monotributo => "06",
       :nota_credito_a => "03",
-      :nota_credito_b => "08"
+      :nota_credito_b => "08",
+      :nota_debito_a => "02",
+      :nota_debito_b => "07"
     }
   }
 end

From 17c76a915eecfdd22216826ccefa73e2a8f1b21b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 20:18:42 -0700
Subject: [PATCH 12/49] Captura de error en el token de WSAA

---
 lib/bravo/bill.rb | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index ab1a5dd..67167a5 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -106,8 +106,8 @@ def next_bill_number
       resp.to_hash[:fe_comp_ultimo_autorizado_response][:fe_comp_ultimo_autorizado_result][:cbte_nro].to_i + 1
     end
 
-    def authorized?
-      !response.nil? && response.header_result == "A" && response.detail_result == "A"
+    def authorized?       
+        !response.nil? && response.header_result == "A" && response.detail_result == "A"
     end
 
     private
@@ -122,15 +122,25 @@ def setup_response(response)
       # TODO: turn this into an all-purpose Response class
 
       result          = response[:fecae_solicitar_response][:fecae_solicitar_result]
-
+          
+      if not result[:fe_det_resp] or not result[:fe_cab_resp] then 
+      # Si no obtuvo respuesta ni cabecera ni detalle, evito hacer '[]' sobre algo indefinido.                        
+      # Ejemplo: Error con el token-sign de WSAA
+          keys, values = {
+                :errores => result[:errors],
+                :header_result => {:resultado => "X" },
+                :observaciones => nil
+          }.to_a.transpose
+          self.response = (defined?(Struct::ResponseMal) ? Struct::ResponseMal : Struct.new("ResponseMal", *keys)).new(*values)         
+          return
+      end       
+      
       response_header = result[:fe_cab_resp]
       response_detail = result[:fe_det_resp][:fecae_det_response]
 
       request_header  = body["FeCAEReq"]["FeCabReq"].underscore_keys.symbolize_keys
       request_detail  = body["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"].underscore_keys.symbolize_keys
-
       iva             = request_detail.delete(:iva)["AlicIva"].underscore_keys.symbolize_keys
-
       request_detail.merge!(iva) 
          
       if result[:errors] then

From d67de6f8fb7c709b0dbf7f1a34e616d24be60db3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 20:36:43 -0700
Subject: [PATCH 13/49] =?UTF-8?q?Corregido=20error=20de=20redondeo=20en=20?=
 =?UTF-8?q?c=C3=A1lculo=20de=20IVA!?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/bill.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index 67167a5..47bfac8 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -45,7 +45,8 @@ def total
 
     def iva_sum
       @iva_sum = net * Bravo::ALIC_IVA[aliciva_id][1]
-      @iva_sum.round_up_with_precision(2)
+      #@iva_sum.round_up_with_precision(2)
+      @iva_sum.round_with_precision(2) # Arregla error de redondeo !!
     end
 
     def authorize

From eca3ab1dfad23714cb8534d95bc57f9923da6903 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 20:50:06 -0700
Subject: [PATCH 14/49] Removido el IVA 21% Hardcodeado !!!!

---
 lib/bravo/bill.rb | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index 47bfac8..e238dbb 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -45,8 +45,7 @@ def total
 
     def iva_sum
       @iva_sum = net * Bravo::ALIC_IVA[aliciva_id][1]
-      #@iva_sum.round_up_with_precision(2)
-      @iva_sum.round_with_precision(2) # Arregla error de redondeo !!
+      @iva_sum.round_up_with_precision(2)
     end
 
     def authorize
@@ -77,7 +76,7 @@ def setup_bill
                         "ImpTrib"     => 0.00,
                         "Iva"         => {
                           "AlicIva" => {
-                            "Id" => "5",
+                            "Id" => BRAVO::ALIC_IVA[alicuota_iva][0],
                             "BaseImp" => net,
                             "Importe" => iva_sum}}}}}}
 

From 0d1efd5dfbcc1d491c13b366afe3f33fbb196ef2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 20:52:15 -0700
Subject: [PATCH 15/49] Corregido el typo del commit anterior

---
 lib/bravo/bill.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index e238dbb..ccf1d36 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -76,7 +76,7 @@ def setup_bill
                         "ImpTrib"     => 0.00,
                         "Iva"         => {
                           "AlicIva" => {
-                            "Id" => BRAVO::ALIC_IVA[alicuota_iva][0],
+                            "Id" => Bravo::ALIC_IVA[alicuota_iva][0],
                             "BaseImp" => net,
                             "Importe" => iva_sum}}}}}}
 

From 770cd75932aae1087dc8ed5157398a8aeb6db0fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 20:56:20 -0700
Subject: [PATCH 16/49] =?UTF-8?q?=C3=8Ddem?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/bill.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index ccf1d36..6bde0d4 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -76,7 +76,7 @@ def setup_bill
                         "ImpTrib"     => 0.00,
                         "Iva"         => {
                           "AlicIva" => {
-                            "Id" => Bravo::ALIC_IVA[alicuota_iva][0],
+                            "Id" => Bravo::ALIC_IVA[alic_iva][0],
                             "BaseImp" => net,
                             "Importe" => iva_sum}}}}}}
 

From 366c69524a918351a2798e5a68b3cee537529884 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Sun, 10 Apr 2011 21:00:10 -0700
Subject: [PATCH 17/49] me.stupid

---
 lib/bravo/bill.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index 6bde0d4..0d9a7b9 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -76,7 +76,7 @@ def setup_bill
                         "ImpTrib"     => 0.00,
                         "Iva"         => {
                           "AlicIva" => {
-                            "Id" => Bravo::ALIC_IVA[alic_iva][0],
+                            "Id" => Bravo::ALIC_IVA[aliciva_id][0],
                             "BaseImp" => net,
                             "Importe" => iva_sum}}}}}}
 

From fbc39e7c4535a20f7aaf896590f4ae6ea2c1cd78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Wed, 13 Apr 2011 17:26:23 -0700
Subject: [PATCH 18/49] =?UTF-8?q?Agregu=C3=A9=20fecha=20de=20emisi=C3=B3n?=
 =?UTF-8?q?=20del=20comprobante=20parametrizable=20(Bill.fch=5Femision)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/bravo/bill.rb | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb
index 0d9a7b9..c156e47 100644
--- a/lib/bravo/bill.rb
+++ b/lib/bravo/bill.rb
@@ -2,7 +2,7 @@ module Bravo
   class Bill
     attr_reader :client, :base_imp, :total
     attr_accessor :net, :doc_num, :iva_cond, :documento, :concepto, :moneda,
-                  :due_date, :aliciva_id, :fch_serv_desde, :fch_serv_hasta,
+                  :due_date, :aliciva_id, :fch_serv_desde, :fch_serv_hasta, :fch_emision,
                   :body, :response
 
     def initialize(attrs = {})
@@ -60,7 +60,12 @@ def authorize
     end
 
     def setup_bill
-      today = Time.new.strftime('%Y%m%d')
+      if fch_emision then
+        fecha_emision = fch_emision.strftime('%Y%m%d')
+      else
+        fecha_emision = Time.new.strftime('%Y%m%d') #today
+      end
+       
 
       fecaereq = {"FeCAEReq" => {
                     "FeCabReq" => Bravo::Bill.header(cbte_type),
@@ -68,7 +73,7 @@ def setup_bill
                       "FECAEDetRequest" => {
                         "Concepto"    => Bravo::CONCEPTOS[concepto],
                         "DocTipo"     => Bravo::DOCUMENTOS[documento],
-                        "CbteFch"     => today,
+                        "CbteFch"     => fecha_emision,
                         "ImpTotConc"  => 0.00,
                         "MonId"       => Bravo::MONEDAS[moneda][:codigo],
                         "MonCotiz"    => exchange_rate,

From 3aa9a3bd1dd69573d61d08db319b41251d8cbe2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= 
Date: Wed, 13 Apr 2011 17:57:18 -0700
Subject: [PATCH 19/49] =?UTF-8?q?correcci=C3=B3n=20menor=20en=20readme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.textile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.textile b/README.textile
index fdfe606..ca27d63 100644
--- a/README.textile
+++ b/README.textile
@@ -28,7 +28,8 @@ make install
 Nota 2: Ojo! Probablemente el openssl instalado originalmente sea el que se acceda por el path. Normalmente esto lo soluciona:
 
 
whereis openssl
-ln -s /usr/local/ssl/bin/openssl RUTA_OBTENIDA_DEL_COMANDO_ANTERIOR
+mv SALIDA_DEL_WHEREIS SALIDA_DEL_WHEREIS_old
+ln -s /usr/local/ssl/bin/openssl SALIDA_DEL_WHEREIS
 
h2. Configuración From 5ed1303299d99c27c3a49a95233a40bf3f33769d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Tue, 3 May 2011 09:36:44 -0700 Subject: [PATCH 20/49] =?UTF-8?q?M=C3=A9todo=20nuevo=20"deleteToken"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/bravo.rb b/lib/bravo.rb index 67f23c8..f1a3489 100644 --- a/lib/bravo.rb +++ b/lib/bravo.rb @@ -30,6 +30,11 @@ def auth_hash def log? Bravo.verbose || ENV["VERBOSE"] end + + def deleteToken + AuthData.deleteToken + end + end From d39c895e6af1b556c9e581736f67e72e58912107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Tue, 3 May 2011 09:37:14 -0700 Subject: [PATCH 21/49] =?UTF-8?q?M=C3=A9todo=20nuevo=20"deleteToken"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo/auth_data.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index e6c3681..2c828e2 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -26,6 +26,11 @@ def fetch Bravo.const_set(k.to_s.upcase, v) unless Bravo.const_defined?(k.to_s.upcase) end end + + def deleteToken + todays_datafile = Dir.pwd + "/tmp/bravo_#{Bravo.cuit}_#{Time.new.strftime('%d_%m_%Y')}.yml" + %x(rm #{todays_datafile}) + end end end end From fa14530e7c0bf9667ef2639bf9f88577dbaa8943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 10 Jun 2011 08:35:44 -0700 Subject: [PATCH 22/49] Edited lib/bravo/bill.rb via GitHub --- lib/bravo/bill.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index c156e47..f9818d6 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -45,7 +45,8 @@ def total def iva_sum @iva_sum = net * Bravo::ALIC_IVA[aliciva_id][1] - @iva_sum.round_up_with_precision(2) + #@iva_sum.round_up_with_precision(2) + @iva_sum.round(2) end def authorize From cc1b742df69b6e1b76416c81d6a13f745ce337a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Thu, 19 Jan 2012 20:38:12 -0300 Subject: [PATCH 23/49] =?UTF-8?q?Ejecuta=20wsaa-client=20incluso=20si=20no?= =?UTF-8?q?=20tiene=20permisos=20de=20ejecuci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo/auth_data.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index 2c828e2..42f3eae 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -19,7 +19,7 @@ def fetch opts += " -a #{todays_datafile}" unless File.exists?(todays_datafile) - %x(#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}) + %x(bash #{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}) end @data = YAML.load_file(todays_datafile).each do |k, v| From b05035831698ebd06c9f553c0c9f8b7a837a5fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 20 Jan 2012 13:22:01 -0300 Subject: [PATCH 24/49] =?UTF-8?q?Soporte=20para=20m=C3=BAltiples=20IVA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo/bill.rb | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index f9818d6..d24bb93 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -2,8 +2,8 @@ module Bravo class Bill attr_reader :client, :base_imp, :total attr_accessor :net, :doc_num, :iva_cond, :documento, :concepto, :moneda, - :due_date, :aliciva_id, :fch_serv_desde, :fch_serv_hasta, :fch_emision, - :body, :response + :due_date, :fch_serv_desde, :fch_serv_hasta, :fch_emision, + :body, :response, :ivas def initialize(attrs = {}) Bravo::AuthData.fetch @@ -23,6 +23,7 @@ def initialize(attrs = {}) self.moneda = attrs[:moneda] || Bravo.default_moneda self.iva_cond = attrs[:iva_cond] self.concepto = attrs[:concepto] || Bravo.default_concepto + self.ivas = attrs[:ivas] || Array.new # [ 1, 100.00, 10.50 ], [ 2, 100.00, 21.00 ] end def cbte_type @@ -44,7 +45,12 @@ def total end def iva_sum - @iva_sum = net * Bravo::ALIC_IVA[aliciva_id][1] + @iva_sum = 0.0 + self.ivas.each{ |i| + # @iva_sum += i[1] * Bravo::ALIC_IVA[ i[0] ][1] + @iva_sum += i[2] + } + #@iva_sum = net * Bravo::ALIC_IVA[TODO][1] #@iva_sum.round_up_with_precision(2) @iva_sum.round(2) end @@ -67,6 +73,18 @@ def setup_bill fecha_emision = Time.new.strftime('%Y%m%d') #today end + #hash_ivas = Hash.new + array_ivas = Array.new + self.ivas.each{ |i| + array_ivas << { + #hash_ivas.merge!( { + # "AlicIva" => { + "Id" => Bravo::ALIC_IVA[ i[0] ][0], + "BaseImp" => i[1] , + "Importe" => i[2] } + # } #) + } + Rails.logger.debug "HASHIVAS -> " + array_ivas.to_yaml + "\n\n\n" fecaereq = {"FeCAEReq" => { "FeCabReq" => Bravo::Bill.header(cbte_type), @@ -80,11 +98,9 @@ def setup_bill "MonCotiz" => exchange_rate, "ImpOpEx" => 0.00, "ImpTrib" => 0.00, - "Iva" => { - "AlicIva" => { - "Id" => Bravo::ALIC_IVA[aliciva_id][0], - "BaseImp" => net, - "Importe" => iva_sum}}}}}} + "Iva" => { "AlicIva" => array_ivas } # array_ivas #hash_ivas + + }}}} detail = fecaereq["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"] @@ -146,8 +162,11 @@ def setup_response(response) request_header = body["FeCAEReq"]["FeCabReq"].underscore_keys.symbolize_keys request_detail = body["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"].underscore_keys.symbolize_keys - iva = request_detail.delete(:iva)["AlicIva"].underscore_keys.symbolize_keys - request_detail.merge!(iva) + + # Esto no funciona desde que se soportan múltiples alícuotas de iva simultáneas + # FIX ? TO-DO + # iva = request_detail.delete(:iva)["AlicIva"].underscore_keys.symbolize_keys + # request_detail.merge!(iva) if result[:errors] then response_detail.merge!( result[:errors] ) From 61e5a7eac6f054c852c930f94c384c3ced4225bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 20 Jan 2012 13:23:08 -0300 Subject: [PATCH 25/49] cleanup --- lib/bravo/bill.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index d24bb93..ec96576 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -73,18 +73,14 @@ def setup_bill fecha_emision = Time.new.strftime('%Y%m%d') #today end - #hash_ivas = Hash.new + array_ivas = Array.new self.ivas.each{ |i| array_ivas << { - #hash_ivas.merge!( { - # "AlicIva" => { "Id" => Bravo::ALIC_IVA[ i[0] ][0], "BaseImp" => i[1] , "Importe" => i[2] } - # } #) } - Rails.logger.debug "HASHIVAS -> " + array_ivas.to_yaml + "\n\n\n" fecaereq = {"FeCAEReq" => { "FeCabReq" => Bravo::Bill.header(cbte_type), @@ -98,8 +94,7 @@ def setup_bill "MonCotiz" => exchange_rate, "ImpOpEx" => 0.00, "ImpTrib" => 0.00, - "Iva" => { "AlicIva" => array_ivas } # array_ivas #hash_ivas - + "Iva" => { "AlicIva" => array_ivas } }}}} detail = fecaereq["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"] From 539878279ace5b479e2b1ea65185d6df9b175fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 20 Jan 2012 14:03:03 -0300 Subject: [PATCH 26/49] Calculo de iva_sum interno --- lib/bravo/bill.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index ec96576..aecfe78 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -47,8 +47,8 @@ def total def iva_sum @iva_sum = 0.0 self.ivas.each{ |i| - # @iva_sum += i[1] * Bravo::ALIC_IVA[ i[0] ][1] - @iva_sum += i[2] + @iva_sum += i[1] * Bravo::ALIC_IVA[ i[0] ][1] + # @iva_sum += i[2] } #@iva_sum = net * Bravo::ALIC_IVA[TODO][1] #@iva_sum.round_up_with_precision(2) From 7758446de54a6c5dfe21b437b69089b71a86d495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 20 Jan 2012 14:03:23 -0300 Subject: [PATCH 27/49] fix en tests --- spec/bravo/bill_spec.rb | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/spec/bravo/bill_spec.rb b/spec/bravo/bill_spec.rb index 850a583..252d943 100644 --- a/spec/bravo/bill_spec.rb +++ b/spec/bravo/bill_spec.rb @@ -50,7 +50,8 @@ @bill.iva_cond = :responsable_inscripto @bill.moneda = :peso @bill.net = 100.89 - @bill.aliciva_id = 2 + + @bill.ivas << [ 2, 100.89 , 21.18 ] @bill.iva_sum.should be_within(0.05).of(21.18) @bill.total.should be_within(0.05).of(122.07) @@ -58,7 +59,9 @@ it "should use give due date an service dates, or todays date" do @bill.net = 100 - @bill.aliciva_id = 2 + + @bill.ivas << [ 2, 100 , 21 ] + @bill.doc_num = "30710151543" @bill.iva_cond = :responsable_inscripto @bill.concepto = "Servicios" @@ -87,7 +90,10 @@ Bravo::BILL_TYPE[Bravo.own_iva_cond].keys.each do |target_iva_cond| it "should authorize a valid bill for #{target_iva_cond.to_s}" do @bill.net = 1000000 - @bill.aliciva_id = 2 + + @bill.ivas << [ 2, 1000000 , 210000 ] + + @bill.doc_num = "30710151543" @bill.iva_cond = target_iva_cond @bill.concepto = "Servicios" @@ -105,7 +111,9 @@ it "should authorize nota de credito A" do @bill.net = 10000 - @bill.aliciva_id = 2 + + @bill.ivas << [ 2, 10000 , 2100 ] + @bill.doc_num = "30710151543" @bill.iva_cond = :nota_credito_a @bill.concepto = "Servicios" @@ -123,7 +131,9 @@ it "should authorize nota de credito B" do @bill.net = 10000 - @bill.aliciva_id = 2 + + @bill.ivas << [ 2, 10000 , 2100 ] + @bill.doc_num = "30710151543" @bill.iva_cond = :nota_credito_b @bill.concepto = "Servicios" From 80de1bc225bb588160e9be0306bad5739e850150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Tue, 15 Jan 2013 15:29:34 -0300 Subject: [PATCH 28/49] Freeze savon version --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index ee41b3c..ba6c5f0 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "http://rubygems.org" platforms :ruby_19 do gem "httpi", "0.7.9" end -gem "savon" +gem "savon", "0.9.7" group :development do platforms :ruby_18 do From e87c341098d7b998f3816cb01969debb254e9254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Tue, 15 Jan 2013 15:39:14 -0300 Subject: [PATCH 29/49] Freezed savon version in gemspec --- bravo.gemspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bravo.gemspec b/bravo.gemspec index e663766..7d4d97b 100644 --- a/bravo.gemspec +++ b/bravo.gemspec @@ -58,7 +58,7 @@ Gem::Specification.new do |s| s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["= 0.9.7"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, ["= 0.11.24"]) s.add_development_dependency(%q, ["= 0.11.6"]) @@ -67,7 +67,7 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, ["~> 1.5.1"]) s.add_development_dependency(%q, [">= 0"]) else - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["= 0.9.7"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["= 0.11.24"]) s.add_dependency(%q, ["= 0.11.6"]) @@ -77,7 +77,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) end else - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["= 0.9.7"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["= 0.11.24"]) s.add_dependency(%q, ["= 0.11.6"]) From ce7b22d55683cde9191096c665e5a6dbee6b5dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Tue, 30 Jun 2015 16:43:56 -0300 Subject: [PATCH 30/49] Debugging wsaa shit --- lib/bravo/auth_data.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index 42f3eae..161df3c 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -19,7 +19,9 @@ def fetch opts += " -a #{todays_datafile}" unless File.exists?(todays_datafile) - %x(bash #{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}) + command = #{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts} + puts "Haciendo request a WSAA: " + command + %x(bash #{command} ) end @data = YAML.load_file(todays_datafile).each do |k, v| From a2d1987455fbd46df48d059d4385c4d5df4b65bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 1 Jul 2015 00:05:31 -0300 Subject: [PATCH 31/49] Please debug all this :shit: --- lib/bravo/auth_data.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index 161df3c..a40858f 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -20,7 +20,7 @@ def fetch unless File.exists?(todays_datafile) command = #{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts} - puts "Haciendo request a WSAA: " + command + Rails.logger.warn "Haciendo request a WSAA: " + command %x(bash #{command} ) end From ff70d2ef4f3586ea6365177bc905c714f937fb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Wed, 1 Jul 2015 00:10:50 -0300 Subject: [PATCH 32/49] :shit: --- lib/bravo/auth_data.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index a40858f..e15aadc 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -19,7 +19,7 @@ def fetch opts += " -a #{todays_datafile}" unless File.exists?(todays_datafile) - command = #{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts} + command = "#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}" Rails.logger.warn "Haciendo request a WSAA: " + command %x(bash #{command} ) end From 49d8b358720b20e9225ddcd5f069016dada6e7aa Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 21 Dec 2018 19:49:46 -0300 Subject: [PATCH 33/49] adding monotributo invoicing --- lib/bravo/bill.rb | 9 +++++++-- lib/bravo/constants.rb | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index aecfe78..c7a8002 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -93,10 +93,15 @@ def setup_bill "MonId" => Bravo::MONEDAS[moneda][:codigo], "MonCotiz" => exchange_rate, "ImpOpEx" => 0.00, - "ImpTrib" => 0.00, - "Iva" => { "AlicIva" => array_ivas } + "ImpTrib" => 0.00 }}}} + if Bravo.own_iva_cond == :responsable_inscripto + fecaereq["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"]["Iva"] = { "AlicIva" => array_ivas } + elsif Bravo.own_iva_cond == :responsable_monotributo and array_ivas.any? + raise "No incluir montos iva al facturar como Responsable Monotributo" + end + detail = fecaereq["FeCAEReq"]["FeDetReq"]["FECAEDetRequest"] detail["DocNro"] = doc_num diff --git a/lib/bravo/constants.rb b/lib/bravo/constants.rb index 8208980..3d62c1a 100644 --- a/lib/bravo/constants.rb +++ b/lib/bravo/constants.rb @@ -45,6 +45,16 @@ module Bravo :nota_credito_b => "08", :nota_debito_a => "02", :nota_debito_b => "07" + }, + responsable_monotributo: { + responsable_inscripto: "11", + consumidor_final: "11", + exento: "11", + responsable_monotributo: "11", + nota_credito_a: "11", + nota_credito_b: "11", + nota_debito_a: "11", + nota_debito_b: "11" } } end From 4a7458423243d242092971b5da56c33ac98792ee Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 4 Jan 2019 18:55:29 -0300 Subject: [PATCH 34/49] precision fix --- lib/bravo/bill.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index aecfe78..f7a975b 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -102,7 +102,7 @@ def setup_bill detail["DocNro"] = doc_num detail["ImpNeto"] = net.to_f detail["ImpIVA"] = iva_sum - detail["ImpTotal"] = total + detail["ImpTotal"] = total.round(2) detail["CbteDesde"] = detail["CbteHasta"] = next_bill_number unless concepto == "Productos" # En "Productos" ("01"), si se mandan estos parámetros la afip rechaza. From 5540bb965a092ac165cce04ac97cfbe8d623801f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Nan?= Date: Wed, 23 Sep 2020 18:26:36 -0300 Subject: [PATCH 35/49] adding related invoice params for A and B notes. New afip requirements --- lib/bravo/bill.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 6cc1603..8fcbb73 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -3,7 +3,7 @@ class Bill attr_reader :client, :base_imp, :total attr_accessor :net, :doc_num, :iva_cond, :documento, :concepto, :moneda, :due_date, :fch_serv_desde, :fch_serv_hasta, :fch_emision, - :body, :response, :ivas + :body, :response, :ivas, :related_invoice_data def initialize(attrs = {}) Bravo::AuthData.fetch @@ -110,6 +110,18 @@ def setup_bill detail["ImpTotal"] = total.round(2) detail["CbteDesde"] = detail["CbteHasta"] = next_bill_number + if related_invoice_data + detail["CbtesAsoc"] = { + "CbteAsoc" => [{ + "Tipo" => related_invoice_data[:type], + "PtoVta" => related_invoice_data[:sale_point], + "Nro" => related_invoice_data[:number], + "Cuit" => related_invoice_data[:cuit], + "CbteFch" => related_invoice_data[:date] + }] + } + end + unless concepto == "Productos" # En "Productos" ("01"), si se mandan estos parámetros la afip rechaza. detail.merge!({"FchServDesde" => fch_serv_desde || today, "FchServHasta" => fch_serv_hasta || today, From e0a50a2ad7bcacc026bcc49b85ea44aabc033593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Nan?= Date: Fri, 25 Sep 2020 20:40:19 -0300 Subject: [PATCH 36/49] [hotfix] adding C notes to constants, it was sending always C invoice code! --- lib/bravo/constants.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/bravo/constants.rb b/lib/bravo/constants.rb index 3d62c1a..cf8e658 100644 --- a/lib/bravo/constants.rb +++ b/lib/bravo/constants.rb @@ -51,10 +51,8 @@ module Bravo consumidor_final: "11", exento: "11", responsable_monotributo: "11", - nota_credito_a: "11", - nota_credito_b: "11", - nota_debito_a: "11", - nota_debito_b: "11" + nota_credito_c: "13", + nota_debito_c: "12" } } end From b0127e42f44415a636f651e87a2b3e68e3e254f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Nan?= Date: Fri, 2 Oct 2020 21:04:01 -0300 Subject: [PATCH 37/49] method to get token last modified date time --- lib/bravo.rb | 6 +++++- lib/bravo/auth_data.rb | 15 +++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/bravo.rb b/lib/bravo.rb index f1a3489..e23c2dc 100644 --- a/lib/bravo.rb +++ b/lib/bravo.rb @@ -34,7 +34,11 @@ def log? def deleteToken AuthData.deleteToken end - + + def token_modified_at + AuthData.token_modified_at + end + end diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index e15aadc..706d035 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -11,13 +11,12 @@ def fetch raise "Archivo certificado no encontrado en #{Bravo.cert}" end - #todays_datafile = "/tmp/bravo_#{Time.new.strftime('%d_%m_%Y')}.yml" - todays_datafile = Dir.pwd + "/tmp/bravo_#{Bravo.cuit}_#{Time.new.strftime('%d_%m_%Y')}.yml" opts = "-u #{Bravo.auth_url}" opts += " -k #{Bravo.pkey}" opts += " -c #{Bravo.cert}" opts += " -a #{todays_datafile}" + unless File.exists?(todays_datafile) command = "#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}" Rails.logger.warn "Haciendo request a WSAA: " + command @@ -30,9 +29,17 @@ def fetch end def deleteToken - todays_datafile = Dir.pwd + "/tmp/bravo_#{Bravo.cuit}_#{Time.new.strftime('%d_%m_%Y')}.yml" %x(rm #{todays_datafile}) - end + end + + def token_modified_at + File.exist?(todays_datafile) ? File.mtime(todays_datafile) : nil + end + + def todays_datafile + Dir.pwd + "/tmp/bravo_#{Bravo.cuit}_#{Time.new.strftime('%d_%m_%Y')}.yml" + end + end end end From b9b1967798cb9712cd71f19f34a612fed6169690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Sun, 25 Oct 2020 21:47:36 -0300 Subject: [PATCH 38/49] =?UTF-8?q?[WIP]=C2=A0Search=20for=20invoices=20and?= =?UTF-8?q?=20such?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo/bill.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 8fcbb73..3ecda66 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -144,6 +144,25 @@ def authorized? !response.nil? && response.header_result == "A" && response.detail_result == "A" end + def search(cbte_type, cbte_nro, pto_vta) + fecompconsultarreq = { + "FeCompConsReq": { + "CbteTipo": cbte_type, + "CbteNro": cbte_nro, + "PtoVta": pto_vta + } + } + body.merge!(fecompconsultarreq) + + response = client.request("FECompConsultar", soap_action: "http://ar.gov.afip.dif.FEV1/FECompConsultar") do |soap| + soap.namespaces["xmlns"] = "http://ar.gov.afip.dif.FEV1/" + soap.body = body + end + puts "FECompConsultar --> " + puts body + return response.to_json + end + private class << self From 27d9a56aa66112148082d2a38735c43ee64ba9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Sun, 25 Oct 2020 22:12:55 -0300 Subject: [PATCH 39/49] =?UTF-8?q?=F0=9F=A4=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bravo/bill.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 3ecda66..cdd9adc 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -146,10 +146,10 @@ def authorized? def search(cbte_type, cbte_nro, pto_vta) fecompconsultarreq = { - "FeCompConsReq": { - "CbteTipo": cbte_type, - "CbteNro": cbte_nro, - "PtoVta": pto_vta + "FeCompConsReq" => { + "CbteTipo" => cbte_type, + "CbteNro" => cbte_nro, + "PtoVta" => pto_vta } } body.merge!(fecompconsultarreq) From cefcbcf32cf06855986780ca5d7f127ffa1ca7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Sun, 25 Oct 2020 22:35:04 -0300 Subject: [PATCH 40/49] Updated to a newer savon gem --- Gemfile | 2 +- bravo.gemspec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index ba6c5f0..ee0d38e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "http://rubygems.org" platforms :ruby_19 do gem "httpi", "0.7.9" end -gem "savon", "0.9.7" +gem "savon", "1.2.0" group :development do platforms :ruby_18 do diff --git a/bravo.gemspec b/bravo.gemspec index 7d4d97b..7085c67 100644 --- a/bravo.gemspec +++ b/bravo.gemspec @@ -58,7 +58,7 @@ Gem::Specification.new do |s| s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, ["= 0.9.7"]) + s.add_runtime_dependency(%q, ["= 1.2.0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, ["= 0.11.24"]) s.add_development_dependency(%q, ["= 0.11.6"]) @@ -67,7 +67,7 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, ["~> 1.5.1"]) s.add_development_dependency(%q, [">= 0"]) else - s.add_dependency(%q, ["= 0.9.7"]) + s.add_dependency(%q, ["= 1.2.0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["= 0.11.24"]) s.add_dependency(%q, ["= 0.11.6"]) @@ -77,7 +77,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) end else - s.add_dependency(%q, ["= 0.9.7"]) + s.add_dependency(%q, ["= 1.2.0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["= 0.11.24"]) s.add_dependency(%q, ["= 0.11.6"]) From 506ac35398162de594588cc200fb54cbd09470b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Thu, 29 Oct 2020 13:41:35 -0300 Subject: [PATCH 41/49] Force savon to log for emergency reasons --- lib/bravo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo.rb b/lib/bravo.rb index e23c2dc..ec9f0b7 100644 --- a/lib/bravo.rb +++ b/lib/bravo.rb @@ -43,6 +43,6 @@ def token_modified_at end Savon.configure do |config| - config.log = Bravo.log? + config.log = true # Bravo.log? config.log_level = :debug end From 8752d83a0f7f97d9df2355cd3ed3b7920928b8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Thu, 29 Oct 2020 13:46:25 -0300 Subject: [PATCH 42/49] Made Savon log through Rails --- lib/bravo.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/bravo.rb b/lib/bravo.rb index ec9f0b7..9232c21 100644 --- a/lib/bravo.rb +++ b/lib/bravo.rb @@ -43,6 +43,7 @@ def token_modified_at end Savon.configure do |config| + config.logger = Rails.logger config.log = true # Bravo.log? config.log_level = :debug end From dd4b0fb18c471b2d952a96e89ce6af74e8dc845e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 30 Oct 2020 14:12:22 -0300 Subject: [PATCH 43/49] Make Savon log always --- lib/bravo/bill.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index cdd9adc..7d01084 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -15,6 +15,11 @@ def initialize(attrs = {}) http.read_timeout = 90 http.open_timeout = 90 http.headers = { "Accept-Encoding" => "gzip, deflate", "Connection" => "Keep-Alive" } + + # Insist because this config doesn't stick from bravo.rb for some reason + config.logger = Rails.logger + config.log = true + config.log_level = :debug end @body = {"Auth" => Bravo.auth_hash} From dac1c01e86ea5e0494b3dfcfd963437042f7bb98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 30 Oct 2020 14:48:03 -0300 Subject: [PATCH 44/49] Hotfix for very old code that keeps failing --- lib/bravo/bill.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 7d01084..7d3167e 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -225,7 +225,10 @@ def setup_response(response) }.merge!(request_header).merge!(request_detail) keys, values = response_hash.to_a.transpose - self.response = (defined?(Struct::Response) ? Struct::Response : Struct.new("Response", *keys)).new(*values) + + #self.response = (defined?(Struct::Response) ? Struct::Response : Struct.new("Response", *keys)).new(*values) + # Even if it throws a warning, it avoids some parsing errors. + self.response = Struct.new("Response", *keys).new(*values) end end end From 251f76f281f7324e775cfb78e023042e5972af75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Nan?= Date: Tue, 5 Jan 2021 15:12:38 -0300 Subject: [PATCH 45/49] getting authentication errors on WSAA requests and raising exception with the api response message --- lib/bravo/auth_data.rb | 21 +++++++++++++++++---- wsaa-client.sh | 20 +++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index 706d035..03a5a20 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -14,22 +14,35 @@ def fetch opts = "-u #{Bravo.auth_url}" opts += " -k #{Bravo.pkey}" opts += " -c #{Bravo.cert}" - opts += " -a #{todays_datafile}" - + opts += " -a #{todays_datafile}" unless File.exists?(todays_datafile) command = "#{File.dirname(__FILE__)}/../../wsaa-client.sh #{opts}" Rails.logger.warn "Haciendo request a WSAA: " + command - %x(bash #{command} ) + rsp = %x(bash #{command} ) end @data = YAML.load_file(todays_datafile).each do |k, v| Bravo.const_set(k.to_s.upcase, v) unless Bravo.const_defined?(k.to_s.upcase) end + + error_msg = nil + if @data["error"].present? + File.delete(todays_datafile) if File.exist?(todays_datafile) + error_msg = "Error autentificando con AFIP: #{@data["error"]}" + elsif not File.exists?(todays_datafile) + error_msg = "Error autentificando con AFIP, vuelva a intentar." + end + + if error_msg + Rails.logger.warn error_msg + raise error_msg + end + end def deleteToken - %x(rm #{todays_datafile}) + %x(rm #{todays_datafile}) end def token_modified_at diff --git a/wsaa-client.sh b/wsaa-client.sh index 0a2cc79..a76b84a 100644 --- a/wsaa-client.sh +++ b/wsaa-client.sh @@ -109,8 +109,14 @@ function ParseTA() if [ "$TOKEN" == "" ] then echo "ERROR: " - echo "$(echo "$RESPONSE" | xmllint --format - | grep faultstring)" - exit 1 + ERROR=$( + echo "$RESPONSE" | + xmllint --format - | + grep faultstring | + xargs + ) + echo $ERROR + #exit 1 fi } #------------------------------------------------------------------------------ @@ -132,10 +138,18 @@ EOF function WriteYAML() { - cat < $DATAFILE +cat < $DATAFILE token: '$TOKEN' sign: '$SIGN' EOF + +if [ "$TOKEN" == "" ] + then +cat <> $DATAFILE +error: '$ERROR' +EOF +fi + } #------------------------------------------------------------------------------ # From dd53dbbc420ab782801e2822971bf990e85e57b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Mon, 7 Jun 2021 14:40:55 -0300 Subject: [PATCH 46/49] Patched constant token/sign setter for multi-tenant environments --- lib/bravo/auth_data.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/auth_data.rb b/lib/bravo/auth_data.rb index 03a5a20..941722b 100644 --- a/lib/bravo/auth_data.rb +++ b/lib/bravo/auth_data.rb @@ -23,7 +23,7 @@ def fetch end @data = YAML.load_file(todays_datafile).each do |k, v| - Bravo.const_set(k.to_s.upcase, v) unless Bravo.const_defined?(k.to_s.upcase) + Bravo.const_set(k.to_s.upcase, v) #unless Bravo.const_defined?(k.to_s.upcase) end error_msg = nil From 85f558cf1d1d5b58a6b733bf130949844f2675a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Sat, 16 Oct 2021 15:49:07 -0300 Subject: [PATCH 47/49] 2021 AFIP update: RIs now use A invoices for MOs (because reasons) --- lib/bravo/constants.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/constants.rb b/lib/bravo/constants.rb index cf8e658..09dc1f9 100644 --- a/lib/bravo/constants.rb +++ b/lib/bravo/constants.rb @@ -40,7 +40,7 @@ module Bravo :responsable_inscripto => "01", :consumidor_final => "06", :exento => "06", - :responsable_monotributo => "06", + :responsable_monotributo => "01", # In 2021 RIs started generating A invoices for MOs. Formerly B: "06", :nota_credito_a => "03", :nota_credito_b => "08", :nota_debito_a => "02", From 235e1f1a3cb0891d7b4b0c9c89641177c12b679d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Fri, 10 Nov 2023 16:04:25 -0300 Subject: [PATCH 48/49] Use PeriodoAsoc when submitting NC/ND without CbteAsoc --- lib/bravo/bill.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index 7d3167e..a203b79 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -125,6 +125,11 @@ def setup_bill "CbteFch" => related_invoice_data[:date] }] } + else + detail["PeriodoAsoc"] = { + "FchDesde" => fch_emision.beginning_of_month.strftime('%Y%m%d'), + "FchHasta" => fch_emision.strftime('%Y%m%d') + } end unless concepto == "Productos" # En "Productos" ("01"), si se mandan estos parámetros la afip rechaza. From 3fdd9ac1bc709b858558d1fd6a2f2443a8192ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Cerrini?= Date: Sat, 11 Nov 2023 16:31:15 -0300 Subject: [PATCH 49/49] User PeriodoAsoc on nc/nd only --- lib/bravo/bill.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bravo/bill.rb b/lib/bravo/bill.rb index a203b79..ce55c1f 100644 --- a/lib/bravo/bill.rb +++ b/lib/bravo/bill.rb @@ -125,7 +125,7 @@ def setup_bill "CbteFch" => related_invoice_data[:date] }] } - else + elsif ["02", "03", "07", "08"].include?(cbte_type) # NC/ND only detail["PeriodoAsoc"] = { "FchDesde" => fch_emision.beginning_of_month.strftime('%Y%m%d'), "FchHasta" => fch_emision.strftime('%Y%m%d')