Vfp y Odoo CRUD o ABM

287 views
Skip to first unread message

Luis Dalmasso

unread,
Dec 3, 2020, 1:25:45 PM12/3/20
to publice...@googlegroups.com
Hace un mes atrás vi algunos post de gente interesada en interactuar entre visual foxpro y odoo, aca les pongo unos ejemplos de como buscar actualizar crear y eliminar registros con el marcado de horas del reloj de personal
que es la tabla  hr.attendance para lo cual deben instalar los modulos de Empleados y asistencias
Además y lo mas importante es instalar el modulo Odoo Rest API  https://github.com/yezyilomo/odoo-rest-api deben copiar el modulo e instalar las dependencias de python3, este modulo expondrá a odoo con una Api Rest con la que realizaremos todas las operaciones

Bueno Espero les sirva ya que esto es muy potente para migrar nuestras aplicaciones a Odoo o integrarlas

Saludos a Todos


********archivo odoo.prg
#Define lAsync .F.
#Define curlserver "http://172.24.64.1:8069"

****VFPJSON https://github.com/sait/vfpjson
****API ODOO https://github.com/yezyilomo/odoo-rest-api

clear
set procedure to json
messagebox(login("misuario", "miclave", "mibasededatos"))
nid=buscar_id_empleado(18354722)
if nid > 0
nidu=buscar_marcado(nid)
endif
centrada="2020-12-03 11:00"
nidn=nuevo_marcado(nid, centrada)
messagebox(nidn)
csalida="2020-12-03 15:00"
marcado_salida(nidu, csalida)

************************


function login( cuser, cpassw, cdb)
***LOGIN  CON POST
JsonDatos =""
TEXT TO  JsonDatos NOSHOW ADDITIVE TEXTMERGE PRETEXT 7
{
    "jsonrpc": "2.0",
    "params": {
        "login": "<<cuser>>",
        "password": "<<cpassw>>",
        "db": "<<cdb>>"
    }
}
endtext

lcUrl = curlserver+"/web/session/authenticate"
loRequest = Createobject('MsXml2.XmlHttp')

loRequest.Open("POST", lcUrl, lAsync )
loRequest.setRequestHeader("Content-Type", "application/json")

loRequest.Send(JsonDatos)
*ojson=json_decode(loRequest.ResponseText)

if cuser $ loRequest.ResponseText
return "OK"
else
if 'Access denied' $ loRequest.responseText
return "Acceso Denegado error de usuario o clave"
else
return "Error"
endif
endif
*******************


function buscar_id_empleado(ndni)

lcUrl = curlserver+'/api/hr.employee?query={ id, identification_id }&filter=[["identification_id", "=", '+ str(ndni,10,0) +']]'
loRequest = Createobject('MsXml2.XmlHttp')
loRequest.Open("GET", lcUrl, lAsync )

loRequest.Send()
ojson=json_decode(loRequest.ResponseText)
if ('"count": 0,' $ loRequest.responseText)
return 0
else
reg=ojson._result.get(1)
return reg._id
endif
***************


function buscar_marcado(id_empleado)

*** BUSQUEDA CON GET
lcUrl = curlserver+'/api/hr.attendance?query={ id, check_in, check_out, display_name }&filter=[["employee_id", "=", '+ str(id_empleado,5,0) +']]'
loRequest = Createobject('MsXml2.XmlHttp')
loRequest.Open("GET", lcUrl, lAsync )

loRequest.Send()
ojson=json_decode(loRequest.ResponseText)
CREATE CURSOR cursor_tickets(id I,check_in C(20), check_out C(20), display_name C(200))
if !('"count": 0,' $ loRequest.responseText)
for n=1 to alen(ojson._result.array)
x=ojson._result.array[n]._id
e=iif(vartype(ojson._result.array[n]._check_in)="L","",ojson._result.array[n]._check_in)
s=iif(vartype(ojson._result.array[n]._check_out)="L","",ojson._result.array[n]._check_out)
d=iif(vartype(ojson._result.array[n]._display_name)="L","",ojson._result.array[n]._display_name)
insert into cursor_tickets ( id, check_in , check_out, display_name ) values (x,e, s, d)
next
endif

if vartype(ojson._error) <> "U"
return ojson._error._data._message
else
reg=ojson._result.get(1)
return reg._id
endif

*!* ? loRequest.Status
*!* ? loRequest.ResponseText


function nuevo_marcado(id_empleado, cingreso)
****INSERT CON POST    2020-12-03 09:18
id_empleado=str(id_empleado,5,0)
JsonDatos =""
TEXT TO  JsonDatos NOSHOW ADDITIVE TEXTMERGE PRETEXT 7
{
    "params": {
        "data": {
            "employee_id": <<id_empleado>>,
            "check_in":"<<cingreso>>"
        }
    }
}
endtext

lcUrl = curlserver+"/api/hr.attendance"
loRequest = Createobject('MsXml2.XmlHttp')

loRequest.Open("POST", lcUrl, lAsync )
loRequest.setRequestHeader("Content-Type", "application/json")

loRequest.Send(JsonDatos)
ojson=json_decode(loRequest.ResponseText)

if vartype(ojson._error) <> "U"
return ojson._error._data._message
else
reg=ojson._result.get(1)
return reg._id
endif


*!* ? loRequest.Status
*!* ? loRequest.ResponseText

function marcado_salida(id_mov, cegreso)
****UPDATE CON PUT
lid_mov=int(id_mov)
id_mov=str(lid_mov,7,0)

JsonDatos =""
TEXT TO  JsonDatos NOSHOW ADDITIVE TEXTMERGE PRETEXT 7
{
    "params": {
    "filter": [["id", "=", <<id_mov>>]],
        "data": {
            "check_out" : "<<cegreso>>"
        }
    }
}
endtext

lcUrl = curlserver+"/api/hr.attendance"
loRequest = Createobject('MsXml2.XmlHttp')

loRequest.Open("PUT", lcUrl, lAsync )
loRequest.setRequestHeader("Content-Type", "application/json")

loRequest.Send(JsonDatos)
ojson=json_decode(loRequest.ResponseText)

if vartype(ojson._error) <> "U"
return ojson._error._data._message
else
return ojson._result
endif

Luis A. Dalmasso

luisda...@gmail.com

Mov: +54  9 261  6184282

Mendoza – Argentina

M.C. Estrada Jr.

unread,
Dec 3, 2020, 1:58:38 PM12/3/20
to publice...@googlegroups.com
gracias!

estaré checandolo



--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/CAFn5X%3DKxNQ3cpnXg1jjM9K1iidTeG_xYLx7k7eP0aZ60PZaJVg%40mail.gmail.com.

mapner

unread,
Dec 3, 2020, 3:40:01 PM12/3/20
to Comunidad de Visual Foxpro en Español
Hola Luis,

exactamente hice algo similar hace unos meses, 
por diferentes caminos apuntamos a lo mismo.

Saludos

Ahi va mi versión...

CRLF = CHR(13)+CHR(10)

o = CREATEOBJECT('Vfp2Odoo')


cdb = 'midb'
cpwd = 'pexox2321'
nUI = o.auth(curl,cdb,cusr,cpwd)
IF nUI > 0
cXML = o.CallMethod2XML(cdb,nUI,cpwd,'product.product','search_read')
o.http(curl,cXML)
ENDIF 

**********
*  Interfaz de Datos VFP a Odoo, accediendo por XMLRPC 
*  Mauricio Pistiner - Junio 2020
*
DEFINE CLASS Vfp2Odoo AS SESSION

**********
*
PROCEDURE auth
LPARAMETERS curl,cdb,cusr,cpwd
LOCAL lOk, nRet

nRet =  -1
TRY
cData = TEXTMERGE([{ "jsonrpc": "2.0", "params": {"login": "<<cusr>>", "password": "<<cpwd>>", "db": "<<cdb>>" } }])

oHTTP = CREATEOBJECT('Msxml2.ServerXMLHTTP.6.0')
oHTTP.OPEN("POST", curl,.F.)
oHTTP.SetRequestHeader('Content-Type','application/json')
oHTTP.SEND(cData)
lOk = .T.
CATCH TO loErr
cError = "Error: " + TRANSFORM(loErr.ErrorNo) +  " Mensaje: " + loErr.MESSAGE
ENDTRY
IF lOk
cResponse = oHTTP.responseText
* --- Si el status es diferente a 200, ocurrió algún error de conectividad con el WS ---
IF oHTTP.STATUS = 200
* convierto <> "
p = AT('"uid":',cResponse)
nRet =  INT(VAL(SUBSTR(cResponse,p+6)))
ELSE
cError = "Error: No se logró la conexión con el Web Service."+CRLF+oHTTP.responseText
MESSAGEBOX(cError)
lOk = .F.
ENDIF
oHTTP = NULL
ENDIF

RETURN nRet

ENDPROC

**********
*
PROCEDURE CallMethod2XML
LPARAMETERS cdb, cUid, cpwd, cModel, cMethod, cParamJson
LOCAL cXML, cParamsXML

cParamXML = THIS.ParserJson2XML(EVL(cParamJson,''))

TEXT TO cXML TEXTMERGE NOSHOW
<?xml version="1.0"?>
<methodCall>
<methodName>execute_kw</methodName>
<params>
<param>
        <value><<cDb>></value>
     </param>
<param>
        <value><<cUid>></value>
    </param>
<param>
        <value><<cPwd>></value>
    </param>
<param>
        <value><<cModel>></value>
    </param>
    <param>
        <value><<cMethod>></value>
    </param>
<param>
        <value><<cParamXML>></value>
    </param>
</params>
</methodCall>
ENDTEXT

RETURN cXML

ENDPROC

**********
*
PROCEDURE http
LPARAMETERS curl, cXML
LOCAL oHTTP, cResult

oHTTP = CREATEOBJECT('Msxml2.ServerXMLHTTP.6.0')
oHTTP.OPEN("POST", curl)
oHTTP.SetRequestHeader("Content-Type", "text/xml")
oHTTP.SEND(cXML)

cResult = oHTTP.responseText
IF oHTTP.STATUS = 200 && HTTP OK
MESSAGEBOX(cResult)
ELSE
MESSAGEBOX(TRANSFORM(oHTTP.STATUS) + " "+oHTTP.responseText)
ENDIF

ENDPROC

**********
*
PROCEDURE ParserJson2XML
PARAMETERS cX
PRIVATE p, cStr, nTab

p=1

cStr = ''
nTab = 0
DO WHILE p<=LEN(cX)
ctoken = THIS.gettoken()
nxTab = 0
DO CASE
CASE ctoken = '['
cC = '<array><data>'+CRLF
nxTab = 1
CASE ctoken = ']'
cC = '</data></array>'+CRLF
nxTab = - 1
CASE ctoken = ','
LOOP
CASE EMPTY(ctoken)
LOOP
OTHERWISE
IF ctoken = '\b'
ctoken = ' '
ENDIF
cC = '<value>'+ctoken+'</value>'+CRLF
ENDCASE
IF nxTab < 0
nTab = nTab + nxTab
ENDIF
cStr = cStr +REPLICATE(CHR(9),nTab)+cC
IF nxTab > 0
nTab = nTab + nxTab
ENDIF
ENDDO

RETURN cStr

ENDPROC

**********
*
PROCEDURE gettoken
LOCAL ctoken, lInString, lError, p1

cOper = ',:[]{}'
cStrDelim = '"'+"'"

DO WHILE SUBSTR(cX,p,1)=' ' AND p<= LEN(cX)
p = p + 1
ENDDO
lInString = !lInString AND SUBSTR(cX,p,1) $ cStrDelim
IF lInString
cStrDelim = SUBSTR(cX,p,1)
p = p + 1
p1 = p
DO WHILE SUBSTR(cX,p,1)<>cStrDelim AND p<= LEN(cX)
p = p + 1
ENDDO
IF SUBSTR(cX,p,1)=cStrDelim
ctoken = SUBSTR(cX,p1,p-p1)
p = p + 1
ELSE
lError = .T.
ENDIF
ELSE
IF SUBSTR(cX,p,1)$cOper
ctoken = SUBSTR(cX,p,1)
p = p + 1
ELSE
p1=p
DO WHILE !SUBSTR(cX,p,1) $ SPACE(1)+cOper AND p<= LEN(cX)
p = p + 1
ENDDO
ctoken = SUBSTR(cX,p1,p-p1)
ENDIF
ENDIF

RETURN EVL(ctoken,'')

ENDPROC

ENDDEFINE

Carlos Alfaro

unread,
Dec 3, 2020, 3:55:43 PM12/3/20
to publice...@googlegroups.com

Muchas gracias amigos.

--

Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.

Luis suescún

unread,
Dec 3, 2020, 10:56:16 PM12/3/20
to publice...@googlegroups.com
Muchas gracias Señores.

Reply all
Reply to author
Forward
0 new messages