# WARNING: Locale must be UTF-8! IMPORT util IMPORT com IMPORT os TYPE t_sync_cmd RECORD oper STRING, data STRING END RECORD DEFINE r_cmd t_sync_cmd -- el comando recibido por el server SCHEMA mbs DEFINE start_time DATETIME YEAR TO SECOND DEFINE logs DYNAMIC ARRAY OF STRING DEFINE last_request, last_response STRING DEFINE last_date DATETIME YEAR TO SECOND, pcodn CHAR(4) , cantidad_Datos,i INT CONSTANT dpy_verb=TRUE -- send messages to standard output CONSTANT log_verb=TRUE -- send messages to the errorlog MAIN DEFINE tout, n, x,quean,x1 INTEGER DEFINE d0 DATETIME YEAR TO SECOND DEFINE url, msg STRING DEFINE method, version, headers STRING DEFINE req com.HTTPServiceRequest DEFINE procesa BOOLEAN CALL startlog("err_sync_server.log") CALL check_utf8() RETURNING x, msg IF x != 0 THEN DISPLAY "ERROR: ", msg EXIT PROGRAM 1 END IF OPEN WINDOW w1 WITH FORM "server" ATTRIBUTES(TEXT = "Test Rest Server", STYLE="naked") CALL show_verb("Starting dbsync server: ...") -- Normally, the port is set by the GAS for load balancing -- For standalone tests you can set FGLAPPSERVER environment variable CALL show_verb("Listening on port : "|| NVL(fgl_getenv("FGLAPPSERVER"),"GAS")) # CALL ARG_VAL(1) RETURNING usuarios # CALL ARG_VAL(2) RETURNING clave # CALL show_verb(SFMT("Connecting to database '%1' as user '%2'","smarmotech",usuarios)) # CONNECT TO "smarmotech_t" USER usuarios USING clave CALL com.WebServiceEngine.Start() LET start_time = CURRENT --LET tout=-1 -- timeout: infinite wait --LET tout=5 -- timeout: 5 seconds LET tout=40 -- timeout: 10 seconds IF tout=-1 THEN LET msg="The dbsync server is listening (timeout = infinite wait)." ELSE LET msg="The dbsync server is listening (timeout =",tout USING "-<<<<<<&"," seconds)." END IF CALL show_verb(msg) LET n=0 WHENEVER ERROR CONTINUE WHILE TRUE IF int_flag<>0 THEN LET int_flag=0 EXIT WHILE END IF LET req = com.WebServiceEngine.getHTTPServiceRequest(tout) IF req IS NULL THEN -- timeout CALL show_verb( SFMT("HTTP request timeout...: %1", CURRENT YEAR TO FRACTION)) CONTINUE WHILE END IF LET url = req.getURL() LET method = req.getMethod() IF method IS NULL OR method != "POST" THEN IF method == "GET" THEN -- TODO: Send server status page back CALL req.sendTextResponse(200,NULL,"Welcome to dbsync server for MBS ...") ELSE CALL show_err(SFMT("Unexpected HTTP request: %1", method)) CALL req.sendTextResponse(400,NULL,"Only POST requests supported") END IF CONTINUE WHILE END IF LET version = req.getRequestVersion() IF version IS NULL OR version != "1.1" THEN CALL show_err(SFMT("Unexpected HTTP request version: %1", version)) CONTINUE WHILE END IF LET headers = req.getRequestHeader("DBSync-Client") IF headers IS NULL OR headers!= "mbs" THEN CALL show_err(SFMT("Unexpected HTTP request header DBSync-Client: %1", headers)) CALL req.sendTextResponse(400,NULL,"Bad request") CONTINUE WHILE END IF LET headers = req.getRequestHeader("Content-Type") IF headers IS NULL OR headers NOT MATCHES "dbsync/json*" THEN -- ;Charset=UTF-8 CALL show_err(SFMT("Unexpected HTTP request header Content-Type: %1", headers)) CALL req.sendTextResponse(400,NULL,"Bad request") CONTINUE WHILE END IF IF NOT(read_request(req)) THEN -- si el procesamiento del request da error vuelve al loop CONTINUE WHILE END IF LET n = n + 1 LET d0 = CURRENT CALL show_verb( SFMT("oper [%1]: %2", d0, r_cmd.oper) ) --CALL show_verb( SFMT("data: %1", r_cmd.data) ) CASE r_cmd.oper WHEN "get_status" CALL send_response(req, "SERVER OK") DISPLAY req TO msg WHEN "info" CALL send_response(req, info()) DISPLAY req TO msg WHEN "show_logs" CALL send_response(req, show_logs()) DISPLAY req TO msg WHEN "last_request" CALL send_response(req, last_request()) DISPLAY req TO msg WHEN "geoposicion" LET last_request = r_cmd.data WHEN "clientes" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=clientes()) WHEN "clientes_insert" LET last_response=clientes_insert(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "monedas" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=monedas()) WHEN "envia_info" LET last_response=oportunidades(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "clientes_update" LET last_response=clientes_update(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "clases" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=clases()) WHEN "itbis" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=itbis_descuento()) WHEN "grupos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=grupos()) WHEN "areas" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=areas()) WHEN "usuarios" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=usuarios()) WHEN "tipos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=tipos()) WHEN "precios" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=precios()) WHEN "tipo_negocios" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=tipo_negocios()) WHEN "condiciones" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=condiciones()) WHEN "medidas" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=medidas()) WHEN "productos_display" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=productos_display(r_cmd.data)) WHEN "requisicion" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=requisiciondespacho(r_cmd.data)) WHEN "envia_parametro_p" LET last_response=r_cmd.data LET pcodn = r_cmd.data CLIPPED # DISPLAY "data pcodn ",pcodn LET last_date = CURRENT CALL send_response(req, last_response) WHEN "repuestos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=productos("repuestos")) WHEN "materia_prima" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=productos("materia_prima")) WHEN "productos" LET last_request = r_cmd.data LET last_date = CURRENT DISPLAY "data ",r_cmd.data CALL send_response(req, last_response:=productos("productos")) WHEN "oportunidades" LET last_request = oportunidades(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "gestion_gastos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=gestion_gastos(r_cmd.data)) WHEN "rnc" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=rnc(r_cmd.data)) WHEN "ip_movimientos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_movimientos()) WHEN "cotizacion" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=cotizacion()) WHEN "rep_cotizacion" # S1: Receive the sync request FROM the client LET last_request = r_cmd.data LET last_date = CURRENT # S4: Sent back new records TO the client CALL send_response(req, last_response:=rep_cotizacion(r_cmd.data)) WHEN "ip_transportistas" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_transportistas()) WHEN "ip_bodegas" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_bodegas()) WHEN "ip_existencia" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=existencia()) WHEN "ip_secciones" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_secciones()) WHEN "ip_fechaConteo" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_fechaconteo()) WHEN "ip_tramos" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ip_tramos()) WHEN "ip_data_conteo" LET last_response = ip_descarga_conteo(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "ip_etiquetas" LET last_response = ip_etiquetas(r_cmd.data) LET last_date = CURRENT CALL send_response(req, last_response) WHEN "v_usuarios" LET last_request = v_usuario(r_cmd.data) LET last_date = CURRENT CALL send_response(req,last_request) WHEN "parametros_generales" LET last_request = r_cmd.data DISPLAY "last re ",last_request LET last_date = CURRENT CALL send_response(req, last_response:=parametros_generales()) WHEN "requisiciones" LET last_request = r_cmd.data DISPLAY "last re ",last_request LET last_date = CURRENT CALL send_response(req, last_response:=requisiciones()) WHEN "ip_ordenes" LET last_request = r_cmd.data LET last_date = CURRENT CALL send_response(req, last_response:=ordenes_display()) OTHERWISE LET msg="invalid operation: " || NVL(r_cmd.oper," ") CALL show_err(msg) CALL req.sendTextResponse(404,NULL,msg) CONTINUE WHILE END CASE LET logs[logs.getLength()+1] = "n:",n USING "<<<<", " ", d0, ' "', r_cmd.oper ,'" ' END WHILE END MAIN FUNCTION read_request(req) DEFINE req com.HTTPServiceRequest DEFINE cmd STRING INITIALIZE r_cmd.* TO NULL TRY CALL req.readTextRequest() RETURNING cmd CATCH CALL show_err(SFMT("Unexpected HTTP request read exception: %1", STATUS)) RETURN FALSE END TRY IF LENGTH(cmd) == 0 THEN -- la operacion va a estar vacia y va dar error por invalida RETURN TRUE END IF TRY CALL util.JSON.parse(cmd, r_cmd) # DISPLAY "ENVIO DATA ",cmd," ",r_cmd.data CATCH CALL show_err(SFMT("JSON parse error: %1", STATUS)) RETURN FALSE END TRY RETURN TRUE END FUNCTION FUNCTION send_response(req,res) DEFINE req com.HTTPServiceRequest DEFINE res STRING IF res.getLength() > 50 THEN CALL show_verb( SFMT("Response [%1] -> Length: %2", CURRENT YEAR TO SECOND, LENGTH(res)) ) ELSE CALL show_verb( SFMT("Response [%1] -> %2.", CURRENT YEAR TO SECOND, res.trim()) ) END IF CALL req.setResponseCharset("UTF-8") CALL req.setResponseHeader("dbsync-server","result") CALL req.setResponseHeader("Content-Type","dbsync/json") # DISPLAY res CALL req.sendTextResponse(200,NULL,res) END FUNCTION FUNCTION check_utf8() IF ORD("€") == 8364 AND LENGTH("€") == 1 THEN RETURN 0, NULL ELSE RETURN -1, "Application locale must be UTF-8, with char length semantics" END IF END FUNCTION FUNCTION show_verb(msg) DEFINE msg STRING IF dpy_verb THEN DISPLAY msg END IF IF log_verb THEN CALL errorlog(msg CLIPPED) END IF END FUNCTION FUNCTION show_err(msg) DEFINE msg STRING DISPLAY "ERROR:",msg CALL errorlog(msg CLIPPED) END FUNCTION FUNCTION info() DEFINE b base.StringBuffer LET b = base.StringBuffer.create() CALL b.append("
") CALL b.append("[top][logs][last request]") CALL b.append("")
CALL b.append(util.JSON.format(last_request))
CALL b.append("")
END IF
CALL b.append("")
CALL b.append(util.JSON.format(last_response))
CALL b.append("")
END IF
CALL b.append("")
RETURN b.toString()
END FUNCTION
{FUNCTION usuarios()
DEFINE pusuarios DYNAMIC ARRAY OF RECORD
usuarios VARCHAR(50),
password VARCHAR(50),
ocupacion VARCHAR(100),
sec_vend INT,
nombre VARCHAR(30),
email VARCHAR(50)
END RECORD
DEFINE pusuario RECORD
usuarios VARCHAR(50),
password VARCHAR(50),
ocupacion VARCHAR(100),
sec_vend INT,
nombre VARCHAR(30),
email VARCHAR(50)
END RECORD,
i SMALLINT,
selec STRING
LET selec ="SELECT a.email,' ',a.ocupacion,a.sec_vend,a.nombre,a.email
FROM CRMindata.dbo.vendedores a"
PREPARE comando FROM selec
DECLARE u1 CURSOR FOR comando
LET i=0 FOREACH u1 INTO pusuario.* LET i=i+1 LET pusuarios[i].*=pusuario.*
DISPLAY "SUBIENDO USUARIOS...."
END FOREACH; FREE u1
RETURN util.JSON.stringify(pusuarios)
END FUNCTION
}
{
FUNCTION geolocalizacion(s)
DEFINE s STRING
DEFINE file_out RECORD
contenido STRING,
nomb_arch STRING,
lat FLOAT,
long FLOAT,
i BYTE,
file_ext STRING
END RECORD
DEFINE file_out_mov RECORD
contenido STRING,
nomb_arch STRING,
lat FLOAT,
long FLOAT,
i BYTE,
file_ext STRING
END RECORD,
s_out STRING,
archivo STRING,
borrar INT
DEFINE r RECORD
ERROR STRING
END RECORD
LOCATE file_out.i IN MEMORY
TRY
CALL util.JSON.parse(s, file_out)
CATCH
LET r.error = "FGL ERROR: ", err_get(status)
RETURN util.JSON.stringify(r)
END TRY
IF os.Path.exists(file_out.nomb_arch) THEN
CALL os.Path.delete(file_out.nomb_arch) RETURNING borrar
END IF
CALL file_out.i.writeFile(file_out.nomb_arch)
FREE file_out.i
IF os.Path.size(file_out.nomb_arch)>0 THEN
CALL get_exif_latlong_bdl(file_out.nomb_arch) RETURNING file_out_mov.lat,file_out_mov.long
DISPLAY "latitudes ", file_out_mov.lat," LONG ",file_out_mov.long
ELSE
LET file_out_mov.contenido="NO PUEDO GEOLOCALIZAR ESTA FOTO"
END IF
LET s_out = UTIL.JSON.stringify(file_out_mov)
RETURN s_out
END FUNCTION
}