Ir al contenido


Foto

Paso de parametros en orientacion a objetos(mi primera unidad)


  • Por favor identifícate para responder
3 respuestas en este tema

#1 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 02 mayo 2016 - 06:07

Hola amigos..este es mi primer proyecto de hacer una unidad con orientacion a objetos.

 

Se trata una unidad autenticacionAFIP.pas que contiene una clase login.

 

Esta clase haria todo el trabajo descripto en los requerimientos del WSAA(autenticacion) de AFIP, ya que no quiero usar librerias de terceros.. use codigo openssl y todo funciona correctamente (lo que pasa es que tengo que diagramar una unidad para que la pc lo haga sola)

 

El problema viene dado por el paso de parametros entre los siguiente metodos:

 

guardarxml: con XML Data Binding cargue el schema xsd correspondiente a enviar al afip. el mismo genera  el mensaje del tra..para lo mismo toma una variable de tipo string que es el servicio para el que se requiere la autorización. Y devuelve un TXMLDocument.

 

ahora bien: como paso el TXMLDocument al metodo generarCMS. generarCMS toma el xmlrequest (que es un archivo xml que debe cumplir con el schema que mencione)y obtiene un string que es el certificado cms(son un monton de letras)..

 

obtuve el error

 

e2197 constant object cannot be passed as var parameter

 

buscando encontre esto:

 

http://docwiki.embar...ameter_(Delphi)

 

y falta mas ..el resto de los metodos:

 

el metodo respuestaxml envia el cms junto a la clave privada .key y el certificado .crt de la empresa(en este caso homologacion) a la afip y obtiene un TXMLDocument que contiene los nodos token y sign..estos son parametros para logearse en otros servicios..

 

Con respecto al constructor:

 

tomaria como atributo el servicio (ya que afip reqwuiere un ticket por cada servicio)

y luego tiene token y sign que son atributos que setearia en el cosntructor mismo llamando a obtenersign y obtener token.. estos metodos toman la respuesta xml y leen los nodos..

 

 

aqui la unidad:


delphi
  1. unit UAutenticacionAFIP;
  2.  
  3. interface
  4. uses
  5. XMLIntf, XMLDoc,shellAPI,dialogs,Classes,SOAPHTTPClient;
  6.  
  7. type
  8. TLogin = class
  9. private
  10.  
  11. Fservicio: string;
  12. Fsign: string;
  13. Ftoken: string;
  14. procedure Setservicio(const Value: string);
  15.  
  16. procedure Setsign(const Value: string);
  17.  
  18. procedure Settoken(const Value: string);
  19.  
  20.  
  21.  
  22. public
  23. property token:string read Ftoken write Settoken;
  24. property sign:string read Fsign write Setsign;
  25. property servicio:string read Fservicio write Setservicio;
  26. constructor Loguearse(s:string);
  27. function guardarXML(var servicio:string):TXMLDocument;
  28. function armarsource:string;
  29. function generarCMS(var xml1:TXMLDocument):string;
  30. function respuestaXML(var s:string):TXMLDocument;
  31. function obtenertoken(respuestacms:TXMLDocument):string;
  32. function obtenersign(var xml2:TXMLDocument): string;
  33. end;
  34.  
  35. implementation
  36.  
  37. { TLogin }
  38.  
  39. uses tra,IniFiles,SysUtils,Forms,DateUtils, LoginCms1, loginresponse;
  40. function TLogin.armarsource: string;
  41. var
  42. archivoini:TIniFile;
  43. source,o,serialNumber,C,cn:string;
  44. begin
  45. archivoini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+ 'caja.ini');
  46. o:=archivoini.ReadString('EMPRESA','O','');
  47. serialNumber:=archivoini.ReadString('EMPRESA','CUIT','');
  48. cn:=archivoini.ReadString('EMPRESA','cn','');
  49. C:=archivoini.ReadString('EMPRESA','C','');
  50. source:='C='+C+',o='+o+',serialNumber='+serialNumber+',cn='+cn;
  51. Result:=source;
  52. end;
  53.  
  54. function TLogin.generarCMS(var xml1:TXMLDocument):string;
  55. var
  56. rutabat,textoCMS,linea:string;
  57. archivoCMS:TStringList;
  58.  
  59. begin
  60.  
  61. rutabat:=ExtractFilePath(Application.ExeName)+'certificado\'+'cms.bat';
  62. ShellExecute(0,'open',PWideChar(rutabat),nil, nil,0);
  63. archivoCMS:=TStringList.Create;
  64. archivoCMS.LoadFromFile(xml1.FileName);
  65.  
  66. textocms:=Copy(archivoCMS.Text,23,2714);
  67.  
  68. result:=textoCMS;
  69.  
  70. end;
  71.  
  72. function TLogin.guardarXML(var servicio:string):TXMLDocument;
  73. var
  74. loginticketrequest:IXMLLoginTicketRequestType;
  75. loginheader:IXMLHeaderType;
  76. archivoini:TIniFile;
  77. diai,diaf,horai:string;
  78. XML1:TXMLDocument;
  79.  
  80. begin
  81. //crear archivo xml
  82. XML1 := TXMLDocument.Create(nil);
  83.  
  84. XML1.FileName:='loginticketrequest.xml';
  85.  
  86.  
  87. loginticketrequest:=NewloginTicketRequest;
  88. //asginar valores para loginticketrequest.xml
  89. // version
  90.  
  91. loginticketrequest.Version:='1.0';
  92. //header
  93.  
  94. // uniqueid son constantes
  95.  
  96. loginticketrequest.header.UniqueId:=4325399;
  97. //hora del pedido.. es ahora
  98. diai:=FormatDateTime('yyyy-mm-dd',Now);
  99. diaf:=FormatDateTime('yyyy-mm-dd',IncHour(Now,23));
  100. horai:=FormatDateTime('hh:mm:ss',IncMinute(now,-40));
  101.  
  102. loginticketrequest.header.GenerationTime:=diai+ 'T' + horai;
  103. //hora de finalizacion (1 dia es el maximo);
  104. loginticketrequest.header.ExpirationTime:=diaf+'T'+horai;
  105.  
  106. //servicio a acceder
  107. loginticketrequest.Service:=servicio;
  108. XML1.XML.Add(loginticketrequest.XML);
  109. XML1.Active:=True;
  110.  
  111. XML1.SaveToFile(ExtractFilePath(Application.ExeName) + 'loginticketrequest.xml');
  112. Result:=XML1;
  113. end;
  114.  
  115. constructor TLogin.Loguearse(s:string);
  116. var
  117. cms:string;
  118. xmlrequest,xmlresponse:TXMLDocument;
  119.  
  120. begin
  121. Fservicio:=s;
  122. Fsign:=obtenersign(xmlresponse);
  123. // Ftoken:=obtenertoken(respuestaXML(generarCMS(guardarXML(servicio))));
  124. end;
  125.  
  126. function TLogin.obtenersign(var xml2:TXMLDocument): string;
  127. var
  128. sign:string;
  129. startnode:iXMLNode;
  130. nodohijo:IXMLNode;
  131. xml1:TXMLDocument;
  132. begin
  133. xml2:=xml1;
  134. xml1.FileName:=ExtractFilePath(Application.ExeName) + 'respuestaxml.xml';
  135. xml1.Active:=True;
  136. xml1.LoadFromFile(ExtractFilePath(Application.ExeName) + 'respuestaxml.xml');
  137. startNode := XML1.DocumentElement.ChildNodes[1];
  138. nodohijo:=startnode.ChildNodes[1];
  139. sign:=nodohijo.NodeValue;
  140. ShowMessage(sign);
  141.  
  142. Result:=sign;
  143. end;
  144.  
  145. function TLogin.obtenertoken(respuestacms:TXMLDocument): string;
  146. begin
  147.  
  148. end;
  149.  
  150. function TLogin.respuestaXML(var s:string):TXMLDocument;
  151. var
  152. RIOLogin:THTTPRIO;
  153. xml1:TXMLDocument;
  154. content,cms:string;
  155. begin
  156.  
  157. RIOLogin:=THTTPRIO.Create(nil);
  158. with RIOLogin do
  159. begin
  160. WSDLLocation:='https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl';
  161. Port:='LoginCms';
  162. Service:='LoginCMSService';
  163.  
  164. end;
  165. cms:=s;
  166. xml1:=TXMLDocument.Create(nil);
  167. content:=(RIOLogin as LoginCms).loginCms(cms);
  168. xml1.XML.Text:=content;
  169. xml1.Active:=True;
  170.  
  171. xml1.SaveToFile(ExtractFilePath(Application.ExeName) + 'respuestaxml.xml');
  172.  
  173. end;
  174.  
  175.  
  176.  
  177. procedure TLogin.Setservicio(const Value: string);
  178. begin
  179. Fservicio := Value;
  180. end;
  181.  
  182. procedure TLogin.Setsign(const Value: string);
  183. begin
  184. Fsign := Value;
  185. end;
  186.  
  187.  
  188. procedure TLogin.Settoken(const Value: string);
  189. begin
  190. Ftoken := Value;
  191. end;
  192.  
  193.  
  194. end.

Estiimados les pido me ayuden un poco..jiij


  • 1

#2 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 03 mayo 2016 - 05:08

bueno el error

 

e2197 constant object cannot be passed as var parameter 

 

lo solucione colocando la palabra const como que es un objeto constante.. busque informacion al respecto pero mucho no entendi jeje.

 

luego obtenia un invalid pointer operation al querer llamar un metodo dentro de otro por lo que en la implementacion tuve que hacer algo que desde ya me parece no esta muy bien..:


delphi
  1. login:=TLogin.Loguearse('wsfe');
  2. xml1:=TXMLDocument.Create(nil);
  3. xml1:=login.guardarXML('wsfe');
  4. xml2:=TXMLDocument.Create(nil);
  5. cms:=login.generarCMS(xml1);
  6. xml2:=login.respuestaXML(cms);
  7. sign:=login.obtenersign(xml2);

osea crear el objeto login e ir cargando metodo por metodo en objetos..

de lo contrario deberia colocar todas las funciones dentro de una y llamar a esa..


  • 1

#3 ELKurgan

ELKurgan

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 561 mensajes
  • LocationEspaña

Escrito 03 mayo 2016 - 10:58

Gracias por compartir la solución

 

Saludos


  • 0

#4 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 04 mayo 2016 - 03:56

Gracias por compartir la solución

 

Saludos

 de nada espero te sirva..

 

lo que me falta implementar son 2 cosas:

 

leer la expirationTime del xml anterior: es decir la hora hasta a que sirve el certificado generado..ya que tiene un limite.. y con esa hora comprobar si es necesario pedir un ticket de acceso nuevamente o no.

 

generar varios certificados: para cada servicio que se desee acceder (consulta padron, facturas, etc) se debe pedir un certificado, es decir ejecutar todo el proceso anterior nuevamente...

Para este ultimo me pregunto si habra algun patron de diseño que me sirva..o si debo heredar de la clase TLogin. 

Podria usar prototype quizas.. ya que cambia el servicio a acceder...


  • 0