consumo de API REST con HMG

HMG en Español

Moderator: Rathinagiri

User avatar
edufloriv
Posts: 247
Joined: Thu Nov 08, 2012 3:42 am
DBs Used: DBF, MariaDB, MySQL, MSSQL, MariaDB
Location: PERU

consumo de API REST con HMG

Post by edufloriv »

Saludos mis estimados,

Yo de nuevo :), estoy trabajando en una integración para facturación electrónica (acá en Perú) , la empresa se llama NubeFact, voy a empezar a realizar pruebas y ellos ya me han proporcionado lo siguiente:

1. Una ruta
2. Un token

Debo enviar un .TXT a esa ruta, con ese token a través de una API REST. También me proporcionaron este ejemplo pero está en Visual Fox Pro:

Code: Select all

* #########################################################
* #### INTEGRACIÓN FÁCIL ####
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
* # ESTE CÓDIGO FUNCIONA PARA LA VERSIÓN ONLINE Y OFFLINE
* # Visita www.nubefact.com/integracion para más información
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++

* #########################################################
* #### FORMA DE TRABAJO ####
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
* # PASO 1: Conseguir una RUTA y un TOKEN para trabajar con NUBEFACT (Regístrate o ingresa a tu cuenta en www.nubefact.com).
* # PASO 2: Generar un archivo en formato .JSON o .TXT con una estructura que se detalla en este documento.
* # PASO 3: Enviar el archivo generado a nuestra WEB SERVICE ONLINE u OFFLINE según corresponda usando la RUTA y el TOKEN.
* # PASO 4: Generamos el archivo XML y PDF (Según especificaciones de la SUNAT) y te devolveremos INSTANTÁNEAMENTE los datos del documento generado.
* # Para ver el documento generado ingresa a www.nubefact.com/login con tus datos de acceso, y luego a la opción "Ver Facturas, Boletas y Notas"
* # IMPORTANTE: Enviaremos el XML generado a la SUNAT y lo almacenaremos junto con el PDF, XML y CDR en la NUBE para que tu cliente pueda consultarlo en cualquier momento, si así lo desea.
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++


* #########################################################
* #### PASO 1: CONSEGUIR LA RUTA Y TOKEN ####
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
* # CUENTA DEMO PARA HACER PRUEBAS
* # Puedes usar la siguiente cuenta para hacer pruebas:
* #  - LINK: https://demo.nubefact.com/login
* #  - USUARIO: demo@nubefact.com
* #  - PASSWORD: demo@nubefact.com
* # Una vez que ingreses a esta cuenta ve a la opción API (Integración) para ver la RUTA y el TOKEN los cuales son:
* #  - RUTA: https://demo.nubefact.com/api/v1/03989d1a-6c8c-4b71-b1cd-7d37001deaa0
* #  - TOKEN: d0a80b88cde446d092025465bdb4673e103a0d881ca6479ebbab10664dbc5677
* # También puedes crear una cuenta propia para hacer pruebas más precisas.
* #
* # CREAR UNA CUENTA PROPIA
* #  - Regístrate gratis en www.nubefact.com/register
* #  - Ir la opción API (Integración).
* # IMPORTANTE: Para que la opción API (Integración) de tu cuenta propia esté activada necesitas escribirnos a soporte@nubefact.com o llámanos al teléfono: 01 468 3535 (opción 2) o celular (WhatsApp) 955 598762.
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++

# RUTA para enviar documentos
ruta = "https://demo.nubefact.com/api/v1/03989d1a-6c8c-4b71-b1cd-7d37001deaa0"

# TOKEN para enviar documentos
token = "d0a80b88cde446d092025465bdb4673e103a0d881ca6479ebbab10664dbc5677"


#########################################################
#### PASO 2: GENERAR EL ARCHIVO PARA ENVIAR A NUBEFACT ####
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
# - MANUAL para archivo JSON en el link: https://goo.gl/WHMmSb
# - MANUAL para archivo TXT en el link: https://goo.gl/Lz7hAq
+++++++++++++++++++++++++++++++++++++++++++++++++++++++

* CONSTRUIMOS EL TXT

TipoComprobante = 1
Serie = FFF1
Nummero = 1
Fecha = "09-05-2017"

*# CAPTURAR VARIABLES DESDE UN FORMULARIO PODRÍA USAR LO SIGUIENTE:
* TipoComprobante=thisform.cbodocumento.DisplayValue
* Serie=thisform.cboserie.DisplayValue
* Nummero=thisform.txtnum.Value
* Fecha=thisform.cbodia.DisplayValue+"-"+thisform.cbomes.DisplayValue+"-"+thisform.cboan.DisplayValue
* thisform.Rpta.Caption =  Cliente+" "+TipoComprobante+" "+Serie+" "+Num+" "+Fecha

* CUIDADO! "TEXT TO" no funciona en versiones anteriores a VF8


TEXT TO txt_para_envio NOSHOW TEXT PRETEXT 7
operacion|generar_comprobante|
tipo_de_comprobante|<<TipoComprobante>>|
serie|<<Serie>>|
numero|<<Num>>|
sunat_transaction|1|
cliente_tipo_de_documento|6|
cliente_numero_de_documento|20600695771|
cliente_denominacion|NUBEFACTSA|
cliente_direccion|CALLE LIBERTAD 116 MIRAFLORES - LIMA - PERU|
cliente_email||
cliente_email_1||
cliente_email_2||
fecha_de_emision|<<Fecha>>|
fecha_de_vencimiento||
moneda|1|
tipo_de_cambio||
porcentaje_de_igv|18|
descuento_global||
total_descuento||
total_anticipo||
total_gravada|600|
total_inafecta||
total_exonerada||
total_igv|108|
total_gratuita||
total_otros_cargos||
total|708|
percepcion_tipo||
percepcion_base_imponible||
total_percepcion||
total_incluido_percepcion||
detraccion|false|
observaciones||
documento_que_se_modifica_tipo||
documento_que_se_modifica_serie||
documento_que_se_modifica_numero||
tipo_de_nota_de_credito||
tipo_de_nota_de_debito||
enviar_automaticamente_a_la_sunat|true|
enviar_automaticamente_al_cliente|false|
codigo_unico||
condiciones_de_pago||
medio_de_pago||
placa_vehiculo||
orden_compra_servicio||
tabla_personalizada_codigo||
formato_de_pdf||
item|NIU|001|DETALLE DEL PRODUCTO|1|500|590||500|1|90|590|false|||
item|ZZ|001|DETALLE DEL SERVICIO|5|20|23.60||100|1|18|118|false|||
ENDTEXT

* #########################################################
* #### PASO 3: ENVIAR EL ARCHIVO A NUBEFACT ####
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
* # SI ESTÁS TRABAJANDO CON ARCHIVO JSON
* # - Debes enviar en el HEADER de tu solicitud la siguiente lo siguiente:
* # Authorization = Token token="8d19d8c7c1f6402687720eab85cd57a54f5a7a3fa163476bbcf381ee2b5e0c69"
* # Content-Type = application/json
* # - Adjuntar en el CUERPO o BODY el archivo JSON o TXT
* # SI ESTÁS TRABAJANDO CON ARCHIVO TXT
* # - Debes enviar en el HEADER de tu solicitud la siguiente lo siguiente:
* # Authorization = Token token="8d19d8c7c1f6402687720eab85cd57a54f5a7a3fa163476bbcf381ee2b5e0c69"
* # Content-Type = text/plain
* # - Adjuntar en el CUERPO o BODY el archivo JSON o TXT
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++

post_connect = CreateObject("MSXML2.ServerXMLHTTP")
* Para algunas versiones de XMLHTTP, usar:
*     post_connect = CreateObject("Microsoft.XMLHTTP")
*     post_connect = CreateObject("MSXML2.XMLHTTP")
post_connect.Open("POST", ruta, .F.)
post_connect.setRequestHeader("Content-Type", "text/plain")
post_connect.setRequestHeader("Authorization", "Token token=" + token)
post_connect.Send(txt_para_envio)
txt_respuesta = post_connect.responsetext

* #########################################################
* #### PASO 4: LEER RESPUESTA DE NUBEFACT ####
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++
* # Recibirás una respuesta de NUBEFACT inmediatamente lo cual se debe leer, verificando que no haya errores.
* # Debes guardar en la base de datos la respuesta que te devolveremos.
* # Escríbenos a soporte@nubefact.com o llámanos al teléfono: 01 468 3535 (opción 2) o celular (WhatsApp) 955 598762
* # Puedes imprimir el PDF que nosotros generamos como también generar tu propia representación impresa previa coordinación con nosotros.
* # La impresión del documento seguirá haciéndose desde tu sistema. Enviaremos el documento por email a tu cliente si así lo indicas en el archivo JSON o TXT.
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++

* LEEMOS LA RESPUESTA contenido en txt_respuesta, cada FILA de la respuesta debe ser leido.

MESSAGEBOX(txt_respuesta)
Es primera vez que trabajo con API REST así que mi duda obviamente es esta sección de código que la veo muy similar a nuestro código HMG:

Code: Select all

post_connect = CreateObject("MSXML2.ServerXMLHTTP")
* Para algunas versiones de XMLHTTP, usar:
*     post_connect = CreateObject("Microsoft.XMLHTTP")
*     post_connect = CreateObject("MSXML2.XMLHTTP")
post_connect.Open("POST", ruta, .F.)
post_connect.setRequestHeader("Content-Type", "text/plain")
post_connect.setRequestHeader("Authorization", "Token token=" + token)
post_connect.Send(txt_para_envio)
txt_respuesta = post_connect.responsetext
Mis preguntas son:
- ¿ En HMG funcionará este código ?
- ¿ Cual de los 3 CreateObject debo usar para HMG ?
- ¿ Al hacer la compilación deberé agregar algún .hbc adicional o deberé hacer una compilación normal ?

Y una última cosa, ¿ cual sería el equivalente en HMG para crear el .TXT del ejemplo enteramente en UTF8 ?:

Code: Select all

TEXT TO txt_para_envio NOSHOW TEXT PRETEXT 7
operacion|generar_comprobante|
tipo_de_comprobante|<<TipoComprobante>>|
serie|<<Serie>>|
numero|<<Num>>|
sunat_transaction|1|
cliente_tipo_de_documento|6|
cliente_numero_de_documento|20600695771|
cliente_denominacion|NUBEFACTSA|
cliente_direccion|CALLE LIBERTAD 116 MIRAFLORES - LIMA - PERU|
cliente_email||
cliente_email_1||
cliente_email_2||
fecha_de_emision|<<Fecha>>|
fecha_de_vencimiento||
moneda|1|
tipo_de_cambio||
porcentaje_de_igv|18|
descuento_global||
total_descuento||
total_anticipo||
total_gravada|600|
total_inafecta||
total_exonerada||
total_igv|108|
total_gratuita||
total_otros_cargos||
total|708|
percepcion_tipo||
percepcion_base_imponible||
total_percepcion||
total_incluido_percepcion||
detraccion|false|
observaciones||
documento_que_se_modifica_tipo||
documento_que_se_modifica_serie||
documento_que_se_modifica_numero||
tipo_de_nota_de_credito||
tipo_de_nota_de_debito||
enviar_automaticamente_a_la_sunat|true|
enviar_automaticamente_al_cliente|false|
codigo_unico||
condiciones_de_pago||
medio_de_pago||
placa_vehiculo||
orden_compra_servicio||
tabla_personalizada_codigo||
formato_de_pdf||
item|NIU|001|DETALLE DEL PRODUCTO|1|500|590||500|1|90|590|false|||
item|ZZ|001|DETALLE DEL SERVICIO|5|20|23.60||100|1|18|118|false|||
ENDTEXT
Por favor alguien con experiencia en el uso de API REST con HMG que me tienda una mano para avanzar rápido con esto y no empezar un proceso de prueba y error que me tardará más tiempo.

Agradecido nuevamente con todos con el invaluable apoyo que siempre me han dado.

Un abrazo cordial esperando se encuentren disfrutando de salud Ustedes y sus seres queridos.

Eduardo Flores Rivas


LIMA - PERU
franco
Posts: 921
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Location: Canada

Re: consumo de API REST con HMG

Post by franco »

I can not quite understand what you need, but can you email a invoice to the route.
In my pos system I can create an estimate and email it to a client while he is on the phone with me.
I hear a ding though the phone and he has the estimate on his phone screen.
If you send me your email address I could send you an example.
All The Best,
Franco
Canada
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: consumo de API REST con HMG

Post by jparada »

Hola Eduardo,

Toma el ejemplo tal cual de VFP e intenta cambiar los . por : y utiliza WIN_OLECREATEOBJECT, el archivo de texto es como crear cualquier archivo simple/texto, únicamente respetando la estructura que te comentan y si acaso y esto depende del encode configurado en tu editor de prg debes jugar con las funciones hb_strToUtf8 o hb_Utf8ToStr.

Saludos,
Javier
User avatar
edufloriv
Posts: 247
Joined: Thu Nov 08, 2012 3:42 am
DBs Used: DBF, MariaDB, MySQL, MSSQL, MariaDB
Location: PERU

Re: consumo de API REST con HMG

Post by edufloriv »

Saludos amigos,

Gracias a Franco y Jparada por su gentil respuesta. Voy a realizar las pruebas segùn tus indicaciones jparada, mil gracias.

Franco: te agredeceré si me envias el ejemplo a mi correo edufloriv(arroba)gmail.com


Cordiales saludos y un abrazo a todos.

Eduardo Flores Rivas


LIMA - PERU
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: consumo de API REST con HMG

Post by edk »

Basado en la documentación de esta página https://goo.gl/WHMmSb, hice un ejemplo de este tipo:

Code: Select all

MEMVAR _HMG_SYSDATA
#include "hmg.ch"
#include "hblang.ch"

REQUEST HB_LANG_ESWIN
request HB_CODEPAGE_ESWIN

REQUEST HB_LANG_ES
request HB_CODEPAGE_ES850

*----------------------------------------------------------------------------------*
Function Main

Local cUrl := "https://www.nubefact.com/api/v1/48239908-7ae7-071765d4"		//"https://demo.nubefact.com/api/v1/03989d1a-6c8c-4b71-b1cd-7d37001deaa0"
Local cToken := "8d19d8c7c1f6402687720eab85cd57a54f5a7a3fa163476bbcf381ee2b5e0c69"		//"d0a80b88cde446d092025465bdb4673e103a0d881ca6479ebbab10664dbc5677"
Local nTimeOut := 20  //seconds
Local oRestApi, cResp
Local hFactura, hItem, hGuias, hVenta_al_credito


set( _SET_CODEPAGE, "ES850" )
hb_LangSelect( 'ES')


//prepare json

hFactura := { => }

hFactura ["operacion"] := "generar_comprobante"
hFactura ["tipo_de_comprobante"] := 1         
hFactura ["serie"] := "FFF1"
hFactura ["numero"] := 1
hFactura ["sunat_transaction"] := 1
hFactura ["cliente_tipo_de_documento"] := 6
hFactura ["cliente_numero_de_documento"] := "20600695771"
hFactura ["cliente_denominacion"] := Utf8("NUBEFACT SA")
hFactura ["cliente_direccion"] := Utf8("CALLE LIBERTAD 116 MIRAFLORES - LIMA - PERU")
hFactura ["cliente_email"] := "tucliente@gmail.com"
hFactura ["cliente_email_1"] := ""
hFactura ["cliente_email_2"] := ""
hFactura ["fecha_de_emision"] := hb_DtoC ( hb_Date(), "DD-MM-YYYY" )
hFactura ["fecha_de_vencimiento"] := ""
hFactura ["moneda"] := 1
hFactura ["tipo_de_cambio"] := ""
hFactura ["porcentaje_de_igv"] := 18.00
hFactura ["descuento_global"] := ""
hFactura ["total_descuento"] := ""
hFactura ["total_anticipo"] := ""
hFactura ["total_gravada"] := 600
hFactura ["total_inafecta"] := ""
hFactura ["total_exonerada"] := ""
hFactura ["total_igv"] := 108
hFactura ["total_gratuita"] := ""
hFactura ["total_otros_cargos"] := ""
hFactura ["total"] := 708
hFactura ["total_otros_cargos"] := ""
hFactura ["percepcion_tipo"] := ""
hFactura ["percepcion_base_imponible"] := ""
hFactura ["total_percepcion"] := ""
hFactura ["total_incluido_percepcion"] := ""
hFactura ["total_impuestos_bolsas"] := ""
hFactura ["detraccion"] := .F.
hFactura ["observaciones"] := ""
hFactura ["documento_que_se_modifica_tipo"] := ""
hFactura ["documento_que_se_modifica_serie"] := ""
hFactura ["documento_que_se_modifica_numero"] := ""
hFactura ["tipo_de_nota_de_credito"] := ""
hFactura ["tipo_de_nota_de_debito"] := ""
hFactura ["enviar_automaticamente_a_la_sunat"] := .T.
hFactura ["enviar_automaticamente_al_cliente"] := .F.
hFactura ["condiciones_de_pago"] := ""
hFactura ["medio_de_pago"] := ""
hFactura ["placa_vehiculo"] := ""
hFactura ["orden_compra_servicio"] := ""
hFactura ["formato_de_pdf"] := ""
hFactura ["generado_por_contingencia"] := ""
hFactura ["bienes_region_selva"] := ""
hFactura ["servicios_region_selva"] := ""

//items

aItems := {}

//First item #1
hItem := { => }
hItem ["unidad_de_medida"] := "NIU"
hItem ["codigo"] := "001"
hItem ["codigo_producto_sunat"] := "10000000"
hItem ["descripcion"] := Utf8("DETALLE DEL PRODUCTO")
hItem ["cantidad"] := 1
hItem ["valor_unitario"] := 500
hItem ["precio_unitario"] := 590
hItem ["descuento"] := ""
hItem ["subtotal"] := 500
hItem ["tipo_de_igv"] := 1
hItem ["igv"] := 90
hItem ["total"] := 590
hItem ["anticipo_regularizacion"] := .F.
hItem ["anticipo_documento_serie"] := ""
hItem ["anticipo_documento_numero"] := ""

//add hItem to aItems array
AADD ( aItems , hItem )

//next item #2
hItem := { => }
hItem ["unidad_de_medida"] := "ZZ"
hItem ["codigo"] := "001"
hItem ["codigo_producto_sunat"] := "20000000"
hItem ["descripcion"] := Utf8("DETALLE DEL SERVICIO")
hItem ["cantidad"] := 5
hItem ["valor_unitario"] := 20
hItem ["precio_unitario"] := 23.60
hItem ["descuento"] := ""
hItem ["subtotal"] := 100
hItem ["tipo_de_igv"] := 1
hItem ["igv"] := 18
hItem ["total"] := 118
hItem ["anticipo_regularizacion"] := .F.
hItem ["anticipo_documento_serie"] := ""
hItem ["anticipo_documento_numero"] := ""

//add hItem to aItems array
AADD ( aItems , hItem )

//add aItems to json
hFactura ["items"] := aItems



//guias

aGuias := {}

//First Guias #1
hGuias := { => }
hGuias ["guia_tipo"] := 1
hGuias ["guia_serie_numero"] := "0001-23"

//add hGuias to aGuias array
AADD ( aGuias , hGuias )

//add aGuias to json
hFactura ["guias"] := aGuias


//venta_al_credito

aVenta_al_credito := {}

//First Venta_al_credito #1
hVenta_al_credito := { => }
hVenta_al_credito ["cuota"] := 1
hVenta_al_credito ["fecha_de_pago"] := "11-03-2021"  //some date: hb_DtoC ( dSomeDate , "DD-MM-YYYY" )
hVenta_al_credito ["importe"] := 600

//add hVenta_al_credito to aVenta_al_credito array
AADD ( aVenta_al_credito , hVenta_al_credito )

//Next Venta_al_credito #2
hVenta_al_credito := { => }
hVenta_al_credito ["cuota"] := 2
hVenta_al_credito ["fecha_de_pago"] := "11-04-2021"  //some date: hb_DtoC ( dSomeDate , "DD-MM-YYYY" )
hVenta_al_credito ["importe"] := 200

//add hVenta_al_credito to aVenta_al_credito array
AADD ( aVenta_al_credito , hVenta_al_credito )

//Next Venta_al_credito #3
hVenta_al_credito := { => }
hVenta_al_credito ["cuota"] := 3
hVenta_al_credito ["fecha_de_pago"] := "11-05-2021"  //some date: hb_DtoC ( dSomeDate , "DD-MM-YYYY" )
hVenta_al_credito ["importe"] := 8

//add hVenta_al_credito to aVenta_al_credito array
AADD ( aVenta_al_credito , hVenta_al_credito )

//add aVenta_al_credito to json
hFactura ["venta_al_credito"] := aVenta_al_credito

strfile (hb_jsonEncode( hFactura , .T. ), 'Factura_json.txt')

//Init
BEGIN SEQUENCE WITH {|o| break(o)}
	oRestApi := Win_OleCreateObject( "MSXML2.ServerXMLHTTP" )
	oRestApi:setTimeouts(nTimeout * 1000 /* nResolve */ , nTimeout * 1000 /* nConnect*/ , nTimeout * 1000 /* nSend */, nTimeout * 1000 /* nReceive */ )

RECOVER
     MsgStop( "Microsoft XML Core Services (MSXML) 6.0 is not installed."+CRLF+;
          "Download and install MSXML 6.0 from http://msdn.microsoft.com/xml"+CRLF+;
          "before continuing.")
     oRestApi:=""

END SEQUENCE

IF EMPTY(oRestApi)
	MsgStop("Error while initialize")
	RETURN Nil
ENDIF


cResp := SendRestApi( cUrl, hb_jsonEncode( hFactura , .F. ), oRestApi, cToken )
Msgdebug (cResp)

hFactura := Nil
hItem :=  Nil
hGuias := Nil
hVenta_al_credito :=  Nil

RETURN

****************************************************************
FUNCTION utf8( cText )
RETURN hb_StrToUtf8( AllTrim(cText) )
*****************************************************************
Function SendRestApi( cUrl, cBody, oRestApi, cToken, cMethod )
Local cReturn

Default cMethod := "POST"

DO EVENTS

BEGIN SEQUENCE WITH {|o| break(o)}

	set( _SET_CODEPAGE, 'UTF8' )

	oRestApi:Open( cMethod, cUrl, .F. )
	oRestApi:setRequestHeader("Content-Type", "application/json;charset=utf-8")
	oRestApi:setRequestHeader("Authorization", cToken)
	oRestApi:Send( cBody )

	set( _SET_CODEPAGE, "ES850" )

	IF oRestApi:Status <> 200
		BREAK "HTTP status: " + hb_NToS(oRestApi:status) + " "  +oRestApi:statusText 
	ENDIF

	cReturn := oRestApi:ResponseBody()
	//or cReturn := oRestApi:ResponseText()

RECOVER USING oErr
	set( _SET_CODEPAGE, "ES850" )
	cReturn := "!ERROR!" + CRLF + HB_TRANSLATE( IF (ValType(oErr) = 'O', oErr:Description, oErr ), 'ESWIN')
 
END SEQUENCE
set( _SET_CODEPAGE, "ES850" )
 	
RETURN cReturn
*****************************************************************************************
Personalmente, es más fácil para mí usar json que plain text, la fuente de prg es más legible.
No sé español, así que utilicé el traductor, pero no sé si entendí todo correctamente. El ejemplo de json es el mismo que en la documentación, pero desafortunadamente los datos de la URL y el token que contiene no me autorizan, por lo que no puedo decir con certeza que todo esté bien.
Aún así, espero haber ayudado un poco.

PS.
Tengo algunas dudas sobre cómo enviar el token. En esta documentación, el título es el siguiente:
CÓMO USAR LA RUTA Y EL TOKEN
Para usar la RUTA y el TOKEN tener en cuenta lo siguiente:

1. Todas las solicitudes se hacen vía POST a la RUTA, ejemplo: https://www.nubefact.com/api/v1/48239908-7ae7-071765d4
2. Debes enviar en el HEADER de tu solicitud lo siguiente:
Authorization 8d19d8c7c1f6402687720eab85cd57a54f5a7a3fa163476bbcf381ee2b5e0c69
Content-Type application/json
3. Adjuntar en el CUERPO o BODY el archivo JSON
4. Recibirás una respuesta inmediatamente.
y en los siguientes ejemplos:
myMSXML.setRequestHeader "Content-Type", "application/json"
myMSXML.setRequestHeader "Authorization", "Token token=" & token
El punto es que no hay Autorization "Token token =" en la descripción y aparece en los ejemplos.
User avatar
Claudio Ricardo
Posts: 367
Joined: Tue Oct 27, 2020 3:38 am
DBs Used: DBF, MySQL, MariaDB
Location: Bs. As. - Argentina

Re: consumo de API REST con HMG

Post by Claudio Ricardo »

Thanks EDK for the example ...
I need to work with something similar and it will be of great use to me.
Question: Do you create as hashes but do you handle them with array functions?
I clarify that I never used hash (it is something new for me)
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: consumo de API REST con HMG

Post by edk »

Claudio Ricardo wrote: Thu Mar 18, 2021 11:50 pm Thanks EDK for the example ...
I need to work with something similar and it will be of great use to me.
Question: Do you create as hashes but do you handle them with array functions?
I clarify that I never used hash (it is something new for me)
Please forgive me, but I'm not a very good teacher, so let me use an example.
Basically a Hash is an array of elements where each element consists of two pairs: a key and a value. The key is a unique name, while the value can be of the following data types: string, numbers, logical values, and arrays (which can contain consecutive Hash or other arrays - as in multidimensional arrays).
json sample.png
json sample.png (28.38 KiB) Viewed 17631 times

Code: Select all

#include "hmg.ch"

*----------------------------------------------------------------------------------*
Function Main


Local hHash, aArray, hHashArray, i


//declare hash
hHash := { => }

//add key "string" to hHash
hHash ["string"] := "any string"

//add key "number" to hHash
hHash ["number"] := 123.45

//add key "logic" to hHash
hHash ["logic"] := .T.

//add key "date" to hHash (date will be encoded as string in DD-MM-YYYY format)
hHash ["date"] := hb_DtoC ( hb_Date(), "DD-MM-YYYY" )

//add key "array" to hHash
//key "array" is an array of hHashArray

//first - prepare empty array
aArray := {}
FOR i=1 TO 5	//array will have 5 elements of hHashArray

	//prepare empty hHashArray for i-th elements
	hHashArray := { => }

	//add 1st key "id" to hHashArray
	hHashArray["id"] := i
	
	//add 2nd key "name" to hHashArray
	hHashArray["name"] := "Any name # " + AllTrim( Str ( i ) )

	//hHashArray have 2 keys -> add this hHashArray to aArray
	AADD( aArray, hHashArray )

NEXT i

//aArray have 5 elements, each element consists of a Hash array containing the "id" and "name" keys
//we assign the value of aArray to the "array" key
hHash ["array"] := aArray

//we already have a hash consisting of the following keys and their data
/* 
  "string": "any string",
  "number": 123.45,
  "logic": true,
  "date": "19-03-2021",
  "array": [ {"id": 1, "name": "Any name # 1"}, {"id": 2, "name": "Any name # 2"}, {"id": 3, "name": "Any name # 3"}, {"id": 4, "name": "Any name # 4"}, {"id": 5,"name": "Any name # 5"} ]
*/

//let's code our hash to json format and save it to the hHash_json.txt file
StrFile (hb_jsonEncode( hHash , .T. ), "hHash_json.txt")

MsgInfo (FileStr ( "hHash_json.txt") )


RETURN
*****************************************************************************************
User avatar
Claudio Ricardo
Posts: 367
Joined: Tue Oct 27, 2020 3:38 am
DBs Used: DBF, MySQL, MariaDB
Location: Bs. As. - Argentina

Re: consumo de API REST con HMG

Post by Claudio Ricardo »

Muchas Gracias EDK por tu respuesta...
No sabía que la vieja función AADD () también podía adicionar datos a un array desde un hash.

//add hVenta_al_credito to aVenta_al_credito array
AADD ( aVenta_al_credito , hVenta_al_credito )

y de ahí vino mi confusión.
Muy agradecido por aclarar mis dudas y enseñarme algo nuevo (para mi) y muy útil.

English with Google traducer:

Thank you very much EDK for your answer ...
I didn't know that the old AADD () function could also add data to an array from a hash.

//add hVenta_al_credito to aVenta_al_credito array
AADD ( aVenta_al_credito , hVenta_al_credito )

And that's where my confusion came from.
Very grateful for clarifying my doubts and teaching me something new (for me) and very useful.
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
User avatar
nekbmm
Posts: 129
Joined: Sat Jul 16, 2016 3:16 am
DBs Used: DBF,SQLite
Location: Ivanjica, Serbia

Re: consumo de API REST con HMG

Post by nekbmm »

Hi edk,

I also need a solution for these api functions in HMG.

/api/login
https://crf.trezor.gov.rs/docs/user/int ... /#apilogin

and how to pass the "accessToken" to the "/api/invoice/register"

/api/invoice/register
https://crf.trezor.gov.rs/docs/user/int ... ceregister

I've tried PowerShell, but it won't work!!!

Thanks in advance nekbmm.
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: consumo de API REST con HMG

Post by edk »

nekbmm wrote: Sun Mar 21, 2021 9:25 am Hi edk,

I also need a solution for these api functions in HMG.

/api/login
https://crf.trezor.gov.rs/docs/user/int ... /#apilogin

and how to pass the "accessToken" to the "/api/invoice/register"

/api/invoice/register
https://crf.trezor.gov.rs/docs/user/int ... ceregister

I've tried PowerShell, but it won't work!!!

Thanks in advance nekbmm.
Check this example

Code: Select all

#include "hmg.ch"

*----------------------------------------------------------------------------------*
Function Main

Local cUrl := "https://rcrf.trezor.gov.rs"		//test url: https://crfrtest.trezor.gov.rs
Local cApiFunction
Local nTimeOut := 20  //seconds
Local oRestApi, cResp, hResp
Local hAtributi, aFaktura
Local cCreationTime, cAccessToken, cRefreshToken

//Init
BEGIN SEQUENCE WITH {|o| break(o)}
	oRestApi := Win_OleCreateObject( "MSXML2.ServerXMLHTTP" )
	oRestApi:setTimeouts(nTimeout * 1000 /* nResolve */ , nTimeout * 1000 /* nConnect*/ , nTimeout * 1000 /* nSend */, nTimeout * 1000 /* nReceive */ )

RECOVER
     MsgStop( "Microsoft XML Core Services (MSXML) 6.0 is not installed."+CRLF+;
          "Download and install MSXML 6.0 from http://msdn.microsoft.com/xml"+CRLF+;
          "before continuing.")
     oRestApi:=""

END SEQUENCE

IF EMPTY(oRestApi)
	MsgStop("Error while initialize")
	RETURN Nil
ENDIF


//login
cApiFunction :=  "/api/login"

//prepare json
hAtributi := { => }

hAtributi ["login"] := "foo"
hAtributi ["password"] := "bar"

strfile (hb_jsonEncode( hAtributi , .F. ), 'login_json.txt')

cResp := SendRestApi( cUrl + cApiFunction, hb_jsonEncode( hAtributi , .F. ), oRestApi )

IF cResp = "!ERROR!"
	MsgStop (cResp)
	oRestApi := Nil
	Quit
ENDIF

IF oRestApi:Status <> 200
	MsgStop ( "HTTP status: " + hb_NToS(oRestApi:status) + " "  +oRestApi:statusText + CRLF + CRLF + "Response: " + cResp )
ENDIF

hResp := hb_jsonDecode( cResp )
cCreationTime := hb_HGetDef( hResp  , "creationTime", "" )
cAccessToken  := hb_HGetDef( hResp  , "accessToken", "" )
cRefreshToken := hb_HGetDef( hResp  , "refreshToken", "" )

IF Empty ( cAccessToken )
	MsgStop ("No accessToken, no authorization !!!")
ENDIF

// register
cApiFunction :=  "/api/invoice/register"

//prepare json
aFaktura := {}

//1st invoice
hAtributi := { => }
hAtributi ["DebtorCompanyNumber"] := "10523"
hAtributi ["InvoiceNumber"]       := "Racun 18/01"
hAtributi ["Amount"]              := 1001
hAtributi ["IssueDate"]           := "2018-02-28"
hAtributi ["Comments"]            := "Komentar 1"

//Add 1st invoice to array
AADD (aFaktura, hAtributi )

//2nd invoice
hAtributi := { => }
hAtributi ["DebtorCompanyNumber"] := "10523"
hAtributi ["InvoiceNumber"]       := "Racun 18/02"
hAtributi ["Amount"]              := 1002.33
hAtributi ["IssueDate"]           := "2018-02-28"
hAtributi ["Comments"]            := "Komentar 2"
hAtributi ["Lifetime"]            := 88

//Add 2nd invoice to array
AADD (aFaktura, hAtributi )

strfile (hb_jsonEncode( aFaktura , .F. ), 'register_json.txt')

cResp := SendRestApi( cUrl + cApiFunction, hb_jsonEncode( hAtributi , .F. ), oRestApi, cAccessToken )

IF cResp = "!ERROR!"
	MsgStop (cResp)
	oRestApi := Nil
	Quit
ENDIF

IF oRestApi:Status <> 200
	MsgStop ( "HTTP status: " + hb_NToS(oRestApi:status) + " "  +oRestApi:statusText + CRLF + CRLF + "Response: " + cResp )
ENDIF

hResp := hb_jsonDecode( cResp )

msgdebug ( hResp )

oRestApi := Nil

RETURN

*****************************************************************
Function SendRestApi( cUrl, cBody, oRestApi, cAuth, cMethod )
Local cReturn

Default cAuth   := ""
Default cMethod := "POST"

DO EVENTS

BEGIN SEQUENCE WITH {|o| break(o)}

	oRestApi:Open( cMethod, cUrl, .F. )
	oRestApi:setRequestHeader("Accept", "*/*")
	oRestApi:setRequestHeader("Content-Type", "application/json")

	IF !Empty ( cAuth )
		oRestApi:setRequestHeader("Authorization", "Bearer " + cAuth)
	ENDIF

	oRestApi:Send( cBody )

	cReturn := oRestApi:ResponseBody()

RECOVER USING oErr

	cReturn := "!ERROR!" + CRLF + IF (ValType(oErr) = 'O', oErr:Description, oErr )
 
END SEQUENCE
 	
RETURN cReturn
*****************************************************************************************
I do not know if it will work because I do not have authorization data, I have no way to check.
I found the Swagger UI https://rcrf.trezor.gov.rs/swagger/index.html and what surprised me is that there is a different json structure for the "/api/invoice/register" function than that given in https://crf.trezor.gov.rs/docs/user/int ... ceregister

I think these are different versions of the API.
Post Reply