# 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("

Servidor de sincronizacion para dispositivos moviles

") CALL b.append("local time: " || CURRENT YEAR TO SECOND || "
") CALL b.append("uptime: "|| CURRENT YEAR TO SECOND - start_time || "
") CALL b.append("Logs
") CALL b.append("Last request
") CALL b.append("") RETURN b.toString() END FUNCTION FUNCTION show_logs() DEFINE b base.StringBuffer DEFINE i INT LET b = base.StringBuffer.create() CALL b.append("") CALL b.append("[top][logs][last request]") CALL b.append("

JSON Sync: Logs

") FOR i = 1 TO logs.getLength() CALL b.append(logs[i]) CALL b.append("
") END FOR CALL b.append("") RETURN b.toString() END FUNCTION FUNCTION last_request() DEFINE b base.StringBuffer LET b = base.StringBuffer.create() CALL b.append("") CALL b.append("[top][logs][last request]") CALL b.append("

JSON Sync: Last Request

") CALL b.append("Date:" || last_date) CALL b.append("

Request:

") IF last_request IS NOT NULL THEN CALL b.append("
")
    CALL b.append(util.JSON.format(last_request))
    CALL b.append("
") END IF CALL b.append("

Response:

") IF last_response IS NOT NULL THEN 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 }