Implementación de SoftwareSistemas y desarrollo

API de CAPATAZ Software (II)

API de CAPATAZ Software (I) Objeto: CAPPS.ul_movstk
Share

Objeto: CAPPS.ul_movstk

Esta nota de Blog forma parte de una saga Objetos COM de la API de CAPATAZ, toda ellas con un título inicial que reza: “API de CAPATAZ Software”, seguido de “Objeto: .
Todas estas notas se relacionan directamente con una nota principal titulada “¿Se puede conectar CAPATAZ con otros Softwares? La API de CAPATAZ Software” y todas poseen las siguientes secciones:
 

  • Denominación: nombre del objeto que debe utilizarse para crear una instancia del mismo.
  • Archivo Contenedor: para conocer su ubicación, versión y todo caso para poder examinar sus miembros.
  • Propósito: breve reseña para indicar la utilidad o capacidades especiales del objeto.
  • Miembros Claves: detalle de algunos métodos y/o propiedades imprescindibles.
  • Ejemplo: un sencillo ejemplo en C# 4.0, con el uso de algunos miembros claves.
  • Anexo: simple enumeración de otros miembros útiles de la clase.

 
Denominación

CAPPS.ul_movstk

 
Archivo Contenedor
CAPPS.EXE
 
Propósito de Uso / Modo de Uso
Es el objeto de Movimientos de Stock, se trata del objeto más versátil y frondoso de la API, y cuenta con números métodos orientados a la Generación de diversos Movimientos de Stock. Por ejemplo: Entregas de Insumos a OT (ECA), Declaraciones de Producción (ICA), Transferencias de Insumos de OT (TIN), REM de Compras, REM de Ventas, Ajustes, Anulaciones, etc.
Como ya expuse en una nota anterior, para utilizar este objeto o cualquier otro primero debemos utilizar el objeto CAPLOGON.ul_logon, para obtener una instancia logueada de éste a CAPATAZ.
Los métodos claves de este objeto requieren un parámetro tipo ADOR.RecordSet que contiene algo así como los renglones del movimiento de stock que deseamos realizar; esto es tal cual, para movimientos de entrada, salida o ajustes, para el caso de transferencias de stock, por cada renglón del ADOR.RecordSet se generan dos renglones en el Movimiento de Stock. La generación de una instancia de este ADOR.RecordSet encierra una complejidad es si misma que trataré de explicar.
 
Dicho todo esto, las tareas que debe llevar a cabo nuestra aplicación externa para generar un Movimiento de Stock en CAPATAZ son 4, a saber:

1. Loguearse al sistema
2. Disponer de un objeto ADOR.RecordSet con los datos del Movimiento de Stock
3. Invocar el método deseado para la generación de un Movimiento de Stock
4. Obtener los resultados de la generación

Para lograr el primer punto, podemos utilizar un objeto CAPLOGON.ul_logon previamente logueado utilizando el método SET_UL_LOGON() o hacer un logueo con el método LOGIN().
El punto 2, hace referencia a un objeto ADOR.RecordSet que requiere un diseño particular, este diseño lo podemos obtener con el método GET_RS_DESING(), expongo aquí ese diseño:
 

Orden Nombre Campo Tipo Ancho Dec Null Req Comentario
1 COD_ARTICU Varchar 15 No VACÍO para indicar que es un renglón adicional.
2 N_PARTIDA Varchar 25 No VACÍO para artículo sin partidas o para numeración automática en Ingresos.
3 CANTIDAD Decimal 17 6 No En Ajustes el signo determina que: Pos(+)=Entrada y Neg(-)=Salida.
4 UME_STK Boolean 1 No Verdadero en Comprobantes Stock, puede ser Falso en Comprobantes Ventas o Compras con cantidad equivalente.
5 COD_DEPOSI Varchar 2 No Depósito del Movimiento ó Depósito Destino en Transferencias.
6 DEPOSI_DDE Varchar 2 No No Depósito Origen en Transferencias solamente.
7 PRECIO Currency 8 4 No No Positivo si el comprobante va a ser valorizado, sino CERO.
8 N_TAL_REF Integer 4 No No Rellenar con el número de talonario del comprobante de Referencia, sino CERO.
9 N_COMP_REF Char 13 No No Rellenar con el número de comprobante del comprobante de Referencia, sino VACÍO.
10 N_RENG_REF Integer 4 No No Rellenar con el renglón del comprobante de Referencia, sino CERO.
11 N_DESPACHO Varchar 25 No No Dato Adicional Opcional de la partida se puede llenar incluso cuando N_PARTIDA=» en Ingresos.
12 PAIS Varchar 20 No No Dato Adicional Opcional de la partida se puede llenar incluso cuando N_PARTIDA=» en Ingresos.
13 ADUANA Varchar 20 No No Dato Adicional Opcional de la partida se puede llenar incluso cuando N_PARTIDA=» en Ingresos.
14 COMENTARIO Varchar 20 No No Dato Adicional Opcional de la partida se puede llenar incluso cuando N_PARTIDA=» en Ingresos.
15 FECHA_VTO Datetime 8 No Dato Adicional Opcional de la partida se puede llenar incluso cuando N_PARTIDA=» en Ingresos.
16 CANT_2UME Decimal 17 6 No No Sólo para Artículos con doble unidad de medida, sino CERO.
17 ID_MEDIDA Integer 4 No No ID de Medida de Stock del artículo si UME_STK=True, sino ID de Medida de Compras ó Ventas.
18 TEXTO30 Varchar 30 No No Texto del campo Descripción del renglón adicional, se ignora en REMP y DEVP.
19 TEXTO20 Varchar 20 No No Texto del campo Descripción Adicional del renglón adicional, se ignora en REMP y DEVP.
20 EQUIVALENC Decimal 17 6 No Si es nulo o cero, se asume la equivalencia de Compra predeterminada ó 1.

Este RecordSet se puede construir manualmente en nuestra aplicación externa o simplemente obtener una instancia del mismo con el diseño requerido vía el método GET_RST() AS ADOR.RecordSet, esta es la forma recomendada y es como lo utilizaremos en nuestro ejemplo.
 
Miembros claves

Nombre Tipo Descripción
Método LOGIN() Boolean Loguea un Usuario a una Empresa para poder utilizar el objeto. Devuelve True si el logueo fue exitoso, de lo contrario False y llena el contenido del parámetro ERR.
Parámetros USU
PASS
ID_EMP
[ref ERR]
String
String
Integer
String
Nombre del usuario de TANGO a loguear.
Password del usuario en TANGO.
Id de la Empresa de TANGO a loguear.
Opcional. Mensaje de error en caso de logueo erróneo.
Nombre Tipo Descripción
Método SET_UL_LOGON () Boolean Establece un objeto de Logueo del tipo CAPLOGON.ul_logon. El objeto debe estar logueado a un usuario y empresa. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro ERR.
Parámetros ref UL_LOGON
[ref ERR]
ul_logon
String
Referencia al objeto CAPLOGON.ul_logon.
Opcional. Mensaje de error en caso de logueo erróneo.
Nombre Tipo Descripción
Método GET_RS_DESING () String Obtiene la estructura de campos que debe tener el RecordSet que se debe utilizar en los métodos de tipo GEN_XXXXXX().
Parámetros [CSV] Boolean Opcional. Si se pasa encendido devuelve el contenido del string en formato de un archivo .CSV.
Nombre Tipo Descripción
Método GET_RST() RecordSet Obtiene una instancia del ADOR.RecordSet con el diseño requerido para los métodos de tipo GEN_XXXXXX().
Nombre Tipo Descripción
Método GET_RST_SER() RecordSet Obtiene una instancia del ADOR.RecordSet con el diseño requerido el método SET_RS_SERIES().
Nombre Tipo Descripción
Método GEN_ECA() Boolean Genera un comprobante de entrega (ECA) para una Orden. Ver método Get_rs_desing() para conocer la estructura del RecordSet de parámetro. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros T_OT
N_OT
ref RS_RENG
[FECHA_MOV]
[OBS_ENTREGA]
[ref MERR]
[COD_PROVEE]
[COD_CLASIF]
String
String
RecordSet
DateTime
String
String
String
String
Tipo de Orden (3 Caracteres)
Número de Orden (13 caracteres X000099999999).
Referencia objeto a ADOR.RecordSet de los Renglones.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Código del Proveedor al que se le entrega.
Opcional. Código de Clasificación CZ del Comprobante.
Nombre Tipo Descripción
Método GEN_ICA() Boolean Genera un comprobante de terminados (ICA) de una Orden genera también una novedad vacía asociada el comprobante. Ver método Get_rs_desing() para conocer la estructura del RecordSet de parámetro. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros T_OT
N_OT
ref RS_RENG
[FECHA_MOV]
[OBS_NOVEDAD]
[ref MERR]
[TIPO_ICA]
[COD_CLASIF]
[CANT_PARTIDAS]
String
String
RecordSet
DateTime
String
String
String
String
Integer
Tipo de Orden (3 Caracteres).
Número de Orden (13 caracteres X000099999999).
Referencia objeto a ADOR.RecordSet de los Renglones.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. T=Terminado, R=Rechazo ó S=SubProducto.
Opcional. Código de Clasificación CZ del Comprobante.
Opcional. Cant de partidas a generar en el ICA, pred=1.
Nombre Tipo Descripción
Método GEN_ECA_DESDE_PIC () Boolean Genera un ECA a partir varios comprobantes de RECOLECCION o PICKING. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros ref RS_RENG
COD_PROVEE
NRO_TAL
N_REMITO
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
RecordSet
String
Integer
String
DateTime
String
String
Referencia objeto a ADOR.RecordSet de los Renglones.
Código del Proveedor.
Nro. del Talonario de Recepción de TANGO.
Nro. Remito (13 caracteres X000099999999).
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Nombre Tipo Descripción
Método GEN_REM_VTAS() Boolean Genera un REMITO DE VENTAS sin referencias. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros ref RS_RENG
COD_CLIENT
NRO_TAL
[COD_TRANSP]
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
[ID_DIR_ENTREGA]
[N_REMITO]
RecordSet
String
Integer
String
DateTime
String
String
Integer
String
Referencia objeto a ADOR.RecordSet de los Renglones.
Código del Cliente.
Nro. Talonario de REMITOS de Venta en TANGO.
Opcional. Código del Transporte.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Id Dirección de Entrega, pred=Habitual.
Opcional. Nro. Remito Externo (X000099999999).
Nombre Tipo Descripción
Método GEN_REM_VTAS_DESDE_PED() Boolean Genera un REMITO DE VENTAS a partir de un PEDIDO. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros TALON_PED
NRO_PEDIDO
ref RS_RENG
COD_CLIENT
NRO_TAL
[COD_TRANSP]
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
[ID_DIR_ENTREGA]
[N_REMITO]
Integer
String
RecordSet
String
Integer
String
DateTime
String
String
Integer
String
Nro. Talonario del Pedido.
Nro. Pedido (X000099999999).
Referencia objeto a ADOR.RecordSet de los Reng.
Código del Cliente.
Nro. Talonario de REMITOS de Venta en TANGO.
Opcional. Código del Transporte.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Id Dirección de Entrega, pred=Habitual.
Opcional. Nro. Remito Externo (X000099999999).
Nombre Tipo Descripción
Método GEN_REM_VTAS_DESDE_PIC() Boolean Genera un REMITO DE VENTAS a partir de una RECOLECCION o PICKING. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros NRO_PIC
ref RS_RENG
COD_CLIENT
NRO_TAL
[COD_TRANSP]
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
[ID_DIR_ENTREGA]
[N_REMITO]
Integer
RecordSet
String
Integer
String
DateTime
String
String
Integer
String
Nro. Comprante de Picking.
Referencia objeto a ADOR.RecordSet de los Reng.
Código del Cliente.
Nro. Talonario de REMITOS de Venta en TANGO.
Opcional. Código del Transporte.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Id Dirección de Entrega, pred=Habitual.
Opcional. Nro. Remito Externo (X000099999999).
Nombre Tipo Descripción
Método GEN_REM_VTAS_DESDE_FAC() Boolean Genera un REMITO DE VENTAS a partir de una RECOLECCION o PICKING. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros NRO_FAC
ref RS_RENG
COD_CLIENT
NRO_TAL
[COD_TRANSP]
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
[ID_DIR_ENTREGA]
[N_REMITO]
String
RecordSet
String
Integer
String
DateTime
String
String
Integer
String
Nro. Factura de Referencia (X000099999999).
Referencia objeto a ADOR.RecordSet de los Reng.
Código del Cliente.
Nro. Talonario de REMITOS de Venta en TANGO.
Opcional. Código del Transporte.
Opcional. Fecha del Movimiento, pred=fecha sys.
Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Id Dirección de Entrega, pred=Habitual.
Opcional. Nro. Remito Externo (X000099999999).
Nombre Tipo Descripción
Método GEN_ACZ() Boolean Genera un AJUSTE DE CAPATAZ. Ver método Get_rs_desing() para conocer la estructura del RecordSet del parámetro RS_RENG. Si se informa el número interno del REM de Recepción (m.ncomp_in_r) se actualizará CZREL_REM_ACZ. Devuelve True si fue exitoso, de lo contrario False y llena el contenido del parámetro MERR.
Parámetros ref RS_RENG
[FECHA_MOV]
[OBSERVACIO]
[ref MERR]
[NCOMP_IN_R]
RecordSet
DateTime
String
String
String
Referencia objeto a ADOR.RecordSet de los Renglones.
Opcional. Fecha del Movimiento, pred=fecha sys.Opcional. Observación del Comprobante de Stock.
Opcional. Mensaje de error en caso de error.
Opcional. Id Dirección de Entrega, pred=Habitual.
Opcional. Nro. Interno del Remito Compras (99999999).

Ejemplo

Con la EMPRESA EJEMPLO que nos establece CAPATAZ, a continuación generaremos un ECA a la OT número 10 generada por 10 LAVARROPAS Modelo V50 (0100200659), en dicho ECA entregaremos:

  • Un EJE TRANSMISOR sin partida porque no utiliza (0200200298)
  • 0.75 Litros de PINTURA AINTIOXIDO de la partida 177 (PINT_0001)

Como ya expuse en un blog anterior, para utilizar este objeto o cualquier otro primero debemos utilizar el objeto CAPLOGON.ul_logon, para obtener una instancia logueada a CAPATAZ (ver blog “API de CAPATAZ Software. Objeto: CAPLOGON.ul_logon”). Utilizaré para el logueo el mismo método que creamos en el Blog mencionado, sólo que lo he convertido a público, tanto el método como la Clase Program, puesto que en aquella oportunidad ambos elementos los creamos como privados, de este modo haremos referencia a dicha clase y utilizaremos el método.
Luego obtendremos una referencia de tipo ADOR.RecordSet, la podríamos obtener fácilmente con el método GET_RST(), pero para aumentar la complejidad y exponer el caso lo haremos manualmente en el método privado. Luego que llenaremos este RecordSet con los insumos a entregar.
Con esté RecordSet invocaremos al método GEN_ECA() y mostraremos los datos del comprobante.

IMPORTANTE: El proyecto de .NET debe ser de 32bits, es decir PlatformTarget=x86.

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ADOR;
using System.Windows.Forms;

namespace Ejemplo02_UL_MOVSTK
{
    class Program
    {
        static void Main(string[] args)
        {
            caplogon.ul_logon oLogUla;

            // Logueo
            if (Ejemplo01_Logueo.Program.Login(out oLogUla))
            {
                Console.WriteLine("\t Ud. está logueado en la Empresa: " + oLogUla.get_emp());
                // Creamos la instancia a CAPPS.ul_movstk y lo logueamos
                var merr = "";
                var umov = new capps.ul_movstk();
                if (umov.set_ul_logon(oLogUla, ref merr))
                {
                    Console.WriteLine("\t Objeto CAPPS.ul_movstk Logueado!");

                    // Obtenemos el ADOR.RecordSet y lo llenamos con los Insumos a Entregar
                    Console.WriteLine(umov.get_rs_desing(true));
                    var rs = CreaRecordSet_ul_movstk();
                    
                    // Un EJE TRANSMISOR sin partida porque no utiliza (0200200298)
                    rs.AddNew();
                    rs.Fields["cod_articu"].Value = "0200200298";
                    rs.Fields["n_partida"].Value = "";
                    rs.Fields["cantidad"].Value = 1;
                    rs.Fields["ume_stk"].Value = true;
                    rs.Fields["cod_deposi"].Value = "1";

                    // 0.75 Litros de PINTURA AINTIOXIDO de la partida 177 (PINT_0001)
                    rs.AddNew();
                    rs.Fields["cod_articu"].Value = "PINT_0001";
                    rs.Fields["n_partida"].Value = "177";
                    rs.Fields["cantidad"].Value = 0.75;
                    rs.Fields["ume_stk"].Value = true;
                    rs.Fields["cod_deposi"].Value = "1";

                    Console.WriteLine("\t Cantidad de Registros en el RecordSet: " + rs.RecordCount);

                    // Generación del ECA
                    var objRs = (object)rs; // Se castea a OBJECT como lo solicita el método.
                    if (umov.GEN_ECA("O/T", " 000000000010", ref objRs, DateTime.Now, "API Capataz", ref merr))
                    {
                        merr = @"Tipo y Nro de Comprobante: " + umov.Tn_comp + Environment.NewLine +
                                " Tipo Interno Comprobante: " + umov.Tcomp_in_s + Environment.NewLine +
                                " Núm. Interno Comprobante: " + umov.Ncomp_in_s;
                        Console.WriteLine(merr);
                    }
                    else
                    {
                        Console.WriteLine(String.Format("@@@ Error @@@{0}{1}", Environment.NewLine, merr.Replace("\r", Environment.NewLine)));
                    }
                    MessageBox.Show(merr);
                }
                else
                {
                    Console.WriteLine(String.Format("@@@ Error @@@{0}{1}", Environment.NewLine, merr));
                    MessageBox.Show(merr);
                }
            }
            else
                Console.ReadKey();
        }

        public static Recordset CreaRecordSet_ul_movstk()
        {
            Recordset rs = new Recordset();
            rs.Fields.Append("cod_articu", DataTypeEnum.adVarChar, 15);
            rs.Fields.Append("n_partida", DataTypeEnum.adVarChar, 25);
            rs.Fields.Append("cantidad", DataTypeEnum.adDecimal, 17);
            rs.Fields["cantidad"].NumericScale = 6;
            rs.Fields.Append("ume_stk", DataTypeEnum.adBoolean);
            rs.Fields.Append("cod_deposi", DataTypeEnum.adVarChar, 2);
            rs.Fields.Append("deposi_dde", DataTypeEnum.adVarChar, 2);
            rs.Fields.Append("precio", DataTypeEnum.adCurrency, 15);
            rs.Fields.Append("n_orden_co", DataTypeEnum.adVarChar, 13);
            rs.Fields.Append("n_rengl_oc", DataTypeEnum.adSmallInt);
            rs.Fields.Append("n_despacho", DataTypeEnum.adVarChar, 20);
            rs.Fields.Append("pais", DataTypeEnum.adVarChar, 20);
            rs.Fields.Append("aduana", DataTypeEnum.adVarChar, 20);
            rs.Fields.Append("comentario", DataTypeEnum.adVarChar, 20);
            rs.Fields.Append("fecha_vto", DataTypeEnum.adDate);
            rs.Fields.Append("fecha_mov", DataTypeEnum.adDate);
            rs.Fields.Append("cant_2ume", DataTypeEnum.adDecimal, 17);
            rs.Fields["cant_2ume"].NumericScale = 6;
            rs.Open();
            return rs;
        }
    }
}

 

Anexo

TN_COMP [Propiedad R/O] AS String
(READONLY) Contiene el tipo y número de comprobante del último movimiento de stock generado por este objeto.
 
TCOMP_IN_S [Propiedad R/O] AS String
(READONLY) Contiene el tipo de comprobante interno del último movimiento de stock generado por este objeto.
 
NCOMP_IN_S [Propiedad R/O] AS String
(READONLY) Contiene el número de comprobante interno del último movimiento de stock generado por este objeto.
 
GEN_MOV_MNC(T_COMP AS String, ByRef RS_RENG AS Object, [ESTAD_ELA AS String], [ESTAD_VTA AS String], [FECHA_MOV AS Date], [COTIZ AS Decimal], [OBSERVACIO AS String], [ByRef MERR AS String]) AS Boolean
Genera un comprobante de Ajuste para una No Conformidad (-) para partida origen y (+) para partida nueva No Conforme.
 
GEN_TIN(T_OT AS String, N_OT AS String, ByRef RS_RENG AS Object, [FECHA_MOV AS Date], [OBS_TRANSF AS String], [ByRef MERR AS String]) AS Boolean
Genera un comprobante de transferencias de insumos (TIN) para una Orden.
 
GEN_TPR(T_OT AS String, N_OT AS String, ByRef RS_RENG AS Object, [FECHA_MOV AS Date], [OBS_TRANSF AS String], [ByRef MERR AS String]) AS Boolean
Genera un comprobante de transferencias de producto (TPR) para una Orden.
 
GEN_ ANUMOVSESION(ID_SESION AS Integer, [ByRef MERR AS String]) AS Boolean
Anula movimientos de STOCK de Capataz para un ID_SESION dado.

ANUMOVEXT(T_COMP AS String, N_COMP AS String, COD_PRO_CL AS String, [ByRef MERR AS String]) AS Boolean
Anula movimientos de STOCK de Capataz, con Números Externos.
 
ANUMOV(TCOMP_IN_S AS String, NCOMP_IN_S AS String, [ByRef MERR AS String], [ANUMOVSDESESION AS Boolean]) AS Boolean
Anula movimientos de STOCK de Capataz, con Números Internos.
 
LEYENDA1 [Propiedad] AS String
Primera Leyenda del comprobante.
 
LEYENDA2 [Propiedad] AS String
Segunda Leyenda del comprobante.
 
LEYENDA3 [Propiedad] AS String
Tercera Leyenda del comprobante.
 
LEYENDA4 [Propiedad] AS String
Cuarta Leyenda del comprobante.
 
LEYENDA5 [Propiedad] AS String
Quinta Leyenda del comprobante.

The following two tabs change content below.
Es Analista en Sistemas y Licenciado en Administración de Empresas. En 2013 culmina su formación en el programa de estudios internacionales ECLA dictado en The Jerome A. Chazen Institute of International Business at Columbia Business School, Columbia University (NY, USA). Desde hace más de 25 años se especializa en el desarrollo y comercialización de software para la toma de decisiones empresariales.

Latest posts by Mauricio Ulla (see all)

Comment here