Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Factura Electronica AFIP Resuelto/Funcionando (https://www.clubdelphi.com/foros/showthread.php?t=88675)

adripugliesso 14-07-2015 23:26:12

Factura Electronica AFIP Resuelto/Funcionando
 
Sin ocx, sin componentes 100% codigo delphi

Tengo el codigo en delphi para solicitar cae y demas funciones del webservice de Afip funcionando 100% codigo puro de delphi sin OCX ni Componentes Raros.

Saludos..


PD: Enseguida pondré enlace al código, que lo subiré al FTP.


.

giulichajari 15-07-2015 17:56:08

Cita:

Empezado por adripugliesso (Mensaje 494460)
Sin ocx, sin componentes 100% codigo delphi

Tengo el codigo en delphi para solicitar cae y demas funciones del webservice de Afip funcionando 100% codigo puro de delphi sin OCX ni Componentes Raros.

Saludos..


PD: Enseguida pondré enlace al código, que lo subiré al FTP.


.

Es decir que te tomaste el trabajo de importar los webservices? y realizar todo el trabajo?
Felicitaciones entonces

adripugliesso 15-07-2015 18:14:57

Claro lo que hice fue importar los WDSL y luego utilizarlos en mi codigo.

egostar 15-07-2015 19:28:35

Cita:

Empezado por adripugliesso (Mensaje 494495)
Claro lo que hice fue importar los WDSL y luego utilizarlos en mi codigo.

Respecto al firmado, ¿que usaste? API, componentes ???

Saludos y felicidades.

adripugliesso 15-07-2015 22:09:20

En el firmado lo unico que hago es usar el shellExecute llamando a un Bat que lo que hace es ejecutar las lineas de Openssl.


Código Delphi [-]
procedure CreaXMLFirmado();
var p1: string;
    r: PAnsiChar;
begin
  memo1.Clear;
  memo1.Lines.Add('c:');
  memo1.Lines.Add('cd /');
  memo1.Lines.Add('cd OpenSSL-Win32');
  memo1.Lines.Add('cd bin');
  memo1.Lines.Add('openssl smime -sign -in ' + ruta + 'ticketsf.xml -out '+ ruta + 'ticketf.xml -inkey ' + ruta + 'cert.key -signer '+ruta +'cert.crt -outform PEM -nodetach ');
  memo1.Lines.SaveToFile(ruta + 'firmar.bat');
  memo1.Clear;

ShellExecute(0, 'open', PAnsiChar(ruta + 'firmar.bat'), 'param1 param2',  nil,  SW_HIDE);
end;

tenes que tener instalado el Openssl en la ruta donde lo llamas

Casimiro Notevi 15-07-2015 22:16:40

Recuerda poner los tags al código fuente, ejemplo:


egostar 15-07-2015 22:19:07

Cita:

Empezado por adripugliesso (Mensaje 494500)
En el firmado lo unico que hago es usar el shellExecute llamando a un Bat que lo que hace es ejecutar las lineas de Openssl.


Código Delphi [-]
procedure CreaXMLFirmado();
var p1: string;
    r: PAnsiChar;
begin
  memo1.Clear;
  memo1.Lines.Add('c:');
  memo1.Lines.Add('cd /');
  memo1.Lines.Add('cd OpenSSL-Win32');
  memo1.Lines.Add('cd bin');
  memo1.Lines.Add('openssl smime -sign -in ' + ruta + 'ticketsf.xml -out '+ ruta + 'ticketf.xml -inkey ' + ruta + 'cert.key -signer '+ruta +'cert.crt -outform PEM -nodetach ');
  memo1.Lines.SaveToFile(ruta + 'firmar.bat');
  memo1.Clear;

ShellExecute(0, 'open', PAnsiChar(ruta + 'firmar.bat'), 'param1 param2',
  nil,  SW_HIDE);
end;

tenes que tener instalado el Openssl en la ruta donde lo llamas

Muy interesante ^\||/, muchas gracias.

Saludos

adripugliesso 03-08-2015 13:53:45

Metodo para Solicitar el CAE
 
Código Delphi [-]
procedure TForm1.Button8Click(Sender: TObject);
var
  port: ServiceSoap;
  respuesta: FECAEResponse;
  Auth: FEAuthRequest;
  Request: FECAERequest;

  CAECabReq : FECAECabRequest;
  CAEDetReq : FECAEDetRequest;
  ACAEDetReq : ArrayOfFECAEDetRequest;
  ADetIva : ArrayOfAlicIva;
  DetIva21 : AlicIva;
  DetIva105 : AlicIva;
  Tributos : Tributo;
  ATributos : ArrayOfTributo;
  CbtesAsoc : CbteAsoc;
  ACbtesAsoc : ArrayOfCbteAsoc;

  x, i : Integer;
  NroComp : Integer;

  iva : boolean;

begin


  screen.Cursor := crHourGlass;


//  edDesde.Text := TimeToStr(now);
  auth      := FeAuthRequest.Create;
  Request   :=  FECAERequest.Create;
  CAEDetReq := FECAEDetRequest.Create;
  CAECabReq := FECAECabRequest.Create;
  DetIva21  := AlicIva.Create;
  DetIva105 := AlicIva.Create;

  SetLength(ACAEDetReq,1);

  Request.FeCabReq        := CAECabReq;
  ACAEDetReq[0]           := CAEDetReq;
  Request.FeDetReq        := ACAEDetReq;

  //si tiene percepciones crea array
//  if STRTOFLOAT(edtPercIIBB.Text) > 0 then
//  begin
//    Tributos := Tributo.Create;
//    SetLength(ATributos,1);
//    ATributos[0]                             := Tributos;
//    Request.FeDetReq[0].Tributos             := ATributos;
//  end;

  //si tiene los 2 ivas dimensiona para 2 sino 1
//  if (STRTOFLOAT(edtIVA105.Text) > 0) and (STRTOFLOAT(edtIVA21.Text) > 0)
//  then
//  begin
//    SetLength(ADetIva,2);
//    ADetIVA[0]              := DetIva21;
//    ADetIVA[1]              := DetIva105;
//    Request.FeDetReq[0].Iva := ADetIva;
//  end
//  else
//  begin
    SetLength(ADetIva,1);
   ADetIVA[0]              := DetIva21;
    Request.FeDetReq[0].Iva := ADetIva;

//  end;


  // si lleva documento vinculado
//  i:= dbTipoCbte.KeyValue;
//  if (i IN [2,3,7,8]) then
//  begin
//    CbtesAsoc := CbteAsoc.Create;
//    SetLength(ACbtesAsoc,1);
//    ACbtesAsoc[0]                             := CbtesAsoc;
//    Request.FeDetReq[0].CbtesAsoc             := ACbtesAsoc;

//  end;


  iva:=false;

  auth.Cuit   := cuit;
  auth.token  := token;
  auth.Sign   := sign;


  //   FeCabReq
  Request.FeCabReq.CantReg  := 1;  //   cantidad de registros
  Request.FeCabReq.CbteTipo := 1;    //   1=fc.A 2=nd.A 3=nc.A    6=fc.B 7=nd.B 8=nc.B
  Request.FeCabReq.PtoVta   := 2;    //   Punto de venta

  //   FecDetReq
  Request.FeDetReq[0].Concepto  := 1;   //   1=productos, 2=servicios, 3=ambos
  Request.FeDetReq[0].DocTipo   := 80; //80 -cuit   86 - cuil   96-dni
  Request.FeDetReq[0].DocNro    := 20000000001; //cuit del cliente

  NroComp := STRTOINT64(edit1.Text);
  
  Request.FeDetReq[0].CbteDesde   := NroComp;
  Request.FeDetReq[0].CbteHasta   := NroComp;
  Request.FeDetReq[0].CbteFch     := formatdatetime('yyyymmdd',now);
  Request.FeDetReq[0].ImpTotal    := 121;
  Request.FeDetReq[0].ImpTotConc  := 0;
  Request.FeDetReq[0].ImpNeto     := 100;
  Request.FeDetReq[0].ImpOpEx     := 0;
  Request.FeDetReq[0].ImpIva      := 21;
  Request.FeDetReq[0].ImpTrib     := 0;  //si tiene percepciones de IIBB o IVA van aca

  if Request.FeDetReq[0].Concepto <> 1 then
  begin
    //------------------------------------------------------------------------
    Request.FeDetReq[0].FchServDesde := FormatDateTime('yyyymmdd',now);         //   solo para concepto 2 o 3
    Request.FeDetReq[0].FchServHasta := FormatDateTime('yyyymmdd',now);          //   solo para concepto 2 o 3
    Request.FeDetReq[0].FchVtoPago   := FormatDateTime('yyyymmdd',now);          //   solo para concepto 2 o 3
    //------------------------------------------------------------------------
  end;

  Request.FeDetReq[0].MonId      := 'PES';
  Request.FeDetReq[0].MonCotiz   := 1;
  //    Request.FeDetReq[0].FchServDesde :=          //   solo para concepto 2 o 3


 // i:= dbTipoCbte.KeyValue;
 // if (i IN [2,3,7,8]) then //es nota de debito o credito lleva doc asociado
 // begin
 //   Request.FeDetReq[0].CbtesAsoc[0].Tipo   := dbTipoCbteVinc.KeyValue;    //  tipo del comprobante asociado (nc/nd)
 //   Request.FeDetReq[0].CbtesAsoc[0].PtoVta := STRTOINT(edtCompVincPto.Text);    //  Punto de venta de la nc
 //   Request.FeDetReq[0].CbtesAsoc[0].Nro    := STRTOINT64(edtCompVincComp.Text);    //  numero de la (nc/nd)
 //end;

  //carga retencion de IIBB si tiene
//  if STRTOFLOAT(edtPercIIBB.Text) > 0 then
//  begin
//      Request.FeDetReq[0].Tributos[0].Id       :=  2;    //2-Imp provincial
//      Request.FeDetReq[0].Tributos[0].Desc     :=  'PERCEPCION DE IIBB BS AS' ;    // Descripcion
//      Request.FeDetReq[0].Tributos[0].BaseImp  :=  STRTOFLOAT(edtSubtotal.Text);    // base imponible
//      Request.FeDetReq[0].Tributos[0].Alic     :=  STRTOFLOAT(edtPercep.Text);    // alicuota
//      Request.FeDetReq[0].Tributos[0].importe  :=  STRTOFLOAT(edtPercIIBB.Text) ;    // imp del tributo
//  end;

  //la factura contiene 2 tipos de iva 10.5 y 21%
//  if (STRTOFLOAT(edtIVA105.Text) > 0) and (STRTOFLOAT(edtIVA21.Text) > 0) then
//  begin
//    Request.FeDetReq[0].Iva[1].id       := 4;     //   alicuota 10.5%
//    Request.FeDetReq[0].Iva[1].BaseImp  := STRTOFLOAT(LNeto105.Caption); //   base imponible
//    Request.FeDetReq[0].Iva[1].importe  := STRTOFLOAT(edtIva105.Text);//   Importe del impuesto
//
//    Request.FeDetReq[0].Iva[0].id       := 5;     //   alicuota 21%
//    Request.FeDetReq[0].Iva[0].BaseImp  := STRTOFLOAT(LNeto21.Caption); //   base imponible
//    Request.FeDetReq[0].Iva[0].importe  := STRTOFLOAT(edtIva21.TExt);//   Importe del impuesto
//    iva := true;
//  end;

  //la factura contiene iva 10.5
//  if (STRTOFLOAT(edtIVA105.Text) > 0) and NOT(iva) then
//  begin
//    Request.FeDetReq[0].Iva[0].id       := 4;     //   alicuota 10.5%
//    Request.FeDetReq[0].Iva[0].BaseImp  := STRTOFLOAT(LNeto105.Caption); //   base imponible
//    Request.FeDetReq[0].Iva[0].importe  := STRTOFLOAT(edtIva105.Text);//   Importe del impuesto
//  end;


  //la factura contiene iva 21
//  if NOT(iva) and (STRTOFLOAT(edtIVA21.Text) > 0) then
//  begin
    Request.FeDetReq[0].Iva[0].id       := 5;     //   alicuota 21%
    Request.FeDetReq[0].Iva[0].BaseImp  := 100; //   base imponible
    Request.FeDetReq[0].Iva[0].importe  := 21;//   Importe del impuesto
//  end;

    //la factura NO LLEVA IVA DISCRIMINADO ES B
//  if (LLetra.Caption = 'B') then
//  begin
//    Request.FeDetReq[0].Iva[0].id       := 3;     //   alicuota 10.5%
//    Request.FeDetReq[0].Iva[0].BaseImp  := STRTOFLOAT(edtSubtotal.Text); //   base imponible
//    Request.FeDetReq[0].Iva[0].importe  := 0;//   Importe del impuesto
//  end;


  //    Request.FeDetReq[0].Opcionales[0].Id    := s(4)    //  id del opcional
  //    Request.FeDetReq[0].Opcionales[0].Valor := s(250); //  valor
  

    port := GetServiceSoap(false,'', httprio1);

    Respuesta := port.FECAESolicitar(Auth,Request );


    Memo1.Lines.Add('RESULTADO: ' + respuesta.fedetresp[0].Resultado);
    Memo1.Lines.Add('CAE: ' + respuesta.fedetresp[0].CAE);
    Memo1.Lines.Add('FECHA VENC: ' + respuesta.fedetresp[0].CAEFchVto);




    //si retorna cae, registra venta
//    if (respuesta.fedetresp[0].Resultado = 'A') then RegistraVenta;




    //--------------------------
    //   ARRAY DE OBSERVACIONES
    //--------------------------
  for x := 0 to high( Respuesta.feDetResp[0].observaciones ) do

      Showmessage('Observ. Code  : '+inttostr(respuesta.fedetresp[0].observaciones[x].Code) +
      ' - Observ. Msg.  : '+respuesta.fedetresp[0].Observaciones[x].Msg);

  
  for x := 0 to High( respuesta.Errors ) do
    Showmessage('Errores : '+inttostr(Respuesta.Errors[x].Code)+' || '+Respuesta.Errors[x].Msg);
   

  auth.Free;
  respuesta.Free;
  Tributos.Free;
  CbtesAsoc.Free;
  DetIva21.Free;
  DetIva105.Free;
 // edHasta.Text := timetostr(now);

  screen.Cursor := crDefault;
end;

AgustinOrtu 03-08-2015 18:57:44

Muy interesante, y eso que lo hiciste por el camino mas dificil ^\||/

El compañero Delphius de DelphiAccess (aunque tambien esta en este foro) propuso en algun momento una iniciativa para implementar los WebService. Seria interesante que el punto de partida sea tu trabajo

Saludos

adripugliesso 04-08-2015 13:46:53

Importate
 
Les comento algo que es clave y sin esto no funcionan los servicios del Webservice de Afip usando WSDL.

1 - Importamos el servicio de WSDL de Afip a nuestra aplicacion para ello vamos a:

Archivo - Nuevos - Otros - Solapa WebService - WDSL Importer

Luego en direccion de importacion ponemos:

Ambiente de prueba (Testing/Homologación):
WS Autenticación y Autorización: https://wsaahomo.afip.gov.ar/ws/services/LoginCms?WSDL
WS Facturación Electrónica: https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL

Ambiente real (Producción):
WS Autenticación y Autorización: https://wsaa.afip.gov.ar/ws/services/LoginCms?WSDL
WS Facturación Electrónica: https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL

Al hacer esto se nos va a agregar a nuestra aplicacion las unit con los metodos directos de los webservice de afip para usar como funciones internas de la aplicacion.

2 - Lo importante y aca viene el secreto es que en las dos unit que se agregan de WSFEv1 hay que ir a la parte de INITIALIZATION y agregar la linea:

Código Delphi [-]
 //se agrega esto
  InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap), ioDocument);

adripugliesso 04-08-2015 23:02:55

Otros Detalles
 
Para los que usen webservice importando el WSDL

Forma de llamar a un método, en este caso (FEParamGetTiposDoc):
Código Delphi [-]
procedure TForm1.Button5Click(Sender: TObject);
var
  FEAuth : FEAuthRequest;
  x : Integer;
  s: DocTipoResponse;
  WS: ServiceSoap;
begin
  screen.Cursor := crHourGlass;

  WS := GetServiceSoap(false,'', httprio1);

  FEAuth  := FEAuthRequest.Create;
  try
    FEAuth.Token := token;
    FEAuth.Sign  := sign;
    FEAuth.Cuit  := cuit;

    Memo1.Clear;

    s := WS.FEParamGetTiposDoc(FEAuth);

    if (Length(s.ResultGet) > 0) then
    begin
      for x := 0 to high( s.ResultGet ) do
      Memo1.lines.Add(
        INTTOSTR(s.ResultGet[x].id)+' || '+
        s.ResultGet[x].Desc+' || '+
        s.ResultGet[x].FchDesde+' || '+
        s.ResultGet[x].FchHasta );
     end;

      if (Length(s.Errors) > 0) then
      showmessage(s.Errors[0].Msg);

  finally
    FEAuth.Free;
    s.Free;
  end;
  screen.Cursor := crDefault;
end;
Lo importante en esto es agregar en el componente HTTPRIO:
Código Delphi [-]
procedure TForm1.HTTPRIO1AfterExecute(const MethodName: String;
  SOAPResponse: TStream);
var
  texto : String;
   f: Integer;
   sl: TStringList;
begin
   SoapResponse.Position := 0;
   f:= FileCreate('after.xml');
   sMemo1.lines.add('===========  AFTER EXECUTE  =====================');
   setlength( texto, SOAPResponse.size );
   soapResponse.Read(Texto[1], SOAPResponse.Size);
   smemo1.lines.add( Texto );
   smemo1.lines.add('----------------------------------------------');
   sMemo1.lines.add( MethodName );
   smemo1.lines.add('======== FIN AFTER EXECUTE ======================');

   FileWrite(f, texto[1], Length(texto));
   FileClose(f);

   sl := TStringList.Create;
   try
     sl.Text := Texto;
     sl.SaveToFile('after-sl.xml');
   finally
     sl.Free;
   end;

end;

Casimiro Notevi 04-08-2015 23:56:37

De nuestra guía de estilo:
Cita:

6. No escribir nunca los mensajes en mayúsculas, esto denota falta de respeto a los foristas.
Escribir en mayúsculas equivale a gritar.

adripugliesso 05-08-2015 00:09:50

disculpas no lo sabia, como lo modifico??

Casimiro Notevi 05-08-2015 00:13:12

Pues es así en todo internet en todo el mundo :)
Voy a editarlo.
Gracias por tu colaboración :)

iMia 19-08-2015 09:37:58

Fantástica aportación y explicación Adripugliesso...
Ye falta explicar el porque de un par de cosas...

- El añadir la llamada "InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap), ioDocument);" en la claúsula Inizialization es por que ese WS no soporta SOAP 1.2 con tipos text/xml... con eso se le indica que el contenido es simplemente text. Es debido a un fallo en los servidores de tomcat que no se suelen configurar de forma correcta.

- En el HTTPRIO, añadir el afterexecute, no es realmente necesario, pero se hace para monitorear los mensajes recibidos y poder guardarlo y analizarlos... pero es algo que se puede obviar...

rruffino 22-04-2016 03:31:32

Consulta
 
Hola, buenas noches!
Yo tambien estoy usando directamente los webservices pero se me ha dado un caso, y es cuando el comprobante a validar solo tiene importes EXENTOS, cuando armo el objeto de Detalle, necesito sacarle el apartado IVA para no presentarlo sino da error en la validacion. Alguien sabe como hacerlo?

giulichajari 23-04-2016 19:48:50

Por lo que veo si has usado openssl, entonces no usas el WSDL de WSAA de autorizacion digamos??

hsbelli 29-04-2016 22:13:02

hola, en que seccion del ftp esta el archivo con los fuentes y como se llama dicho archivo?
gracias!

saludos

fredymam 20-07-2016 16:26:15

Hola!! comunidad

Estaba teniendo el mismo problema en Delphi7 y la corrección que publicaron
Código Delphi [-]
 InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap), ioDocument);
resolvió gran parte :):)

Aunque ahora tengo otro problema con CbtesAsoc, Tributos y Otros; y resulta imposible enviarlos vacíos, dando el siguiente error:

--->> Observaciones:
Code: 10062 - Msg.: Si envia CbtesAsoc, CbteAsoc es obligatorio.
Code: 10052 - Msg.: Si envia Opcionales, Opcional es obligatorio.


Código Delphi [-]
var
  Retenciones : ArrayOfTributo;
  Detalle        : FECAEDetRequest;
begin
  SetLength(Retenciones,0);
  Detalle.CbtesAsoc := Retenciones;

SpyO_O 24-04-2017 07:57:49

OpenSSL
 
Hola Amigo, gracias por el aporte.
Estoy interesado en ver como llamas al webservices "logincms", yo estoy haciendo lo siguiente , pero obtengo siempre el mensaje de error "El CMS es inválido".
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
 vService:uLogincms.LoginCMS;
 vCms:String;
begin
    Memo1.Clear;
    Memo1.Lines.LoadFromFile('C:\Afip\myProject\manual\tra.xml.firmado');
    vcms:=Memo1.Lines.Text;
    vService:=ulogincms.GetLoginCMS();
    Memo1.lines.text:=vService.loginCms(vcms);

La unit uLogincms es el wdsl importado de https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl

Podrías darme una mano con esto por favor? , no encontré en el FTP el código que habias dicho que lo subirías .

Gracias


Cita:

Empezado por adripugliesso (Mensaje 494460)
Sin ocx, sin componentes 100% codigo delphi

Tengo el codigo en delphi para solicitar cae y demas funciones del webservice de Afip funcionando 100% codigo puro de delphi sin OCX ni Componentes Raros.

Saludos..


PD: Enseguida pondré enlace al código, que lo subiré al FTP.


.



La franja horaria es GMT +2. Ahora son las 20:11:53.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi