Buscar en este blog

domingo, 1 de noviembre de 2015

Saldo de cuenta contable por dimensión por código en Dynamics Ax 2012


Anteriormente había publicado cómo consultar el saldo de una cuenta que funciona tanto para cuentas normales como para totalizadoras, en esta ocasión el código a continuación sirve para calcular el saldo de una cuenta con una dimensión especifica hasta una fecha definida haciendo uso de la clase LedgerBalanceDimAttrValueAmounts.

El método requiere como parámetro la cuenta de la que se requiere el saldo, la dimensión que en este caso es una dimensión de sucursal y la fecha hasta donde se requiere el saldo.

private AmountMST saldoCuentaSucursalAx(str _cuenta,
                                           str _sucursal,
                                           date _fechaHasta)
{
       
    LedgerBalanceDimAttrValueAmounts        balance;
    MainAccountListPageBalanceParameters    balanceParaemeters;
    MainAccount                             mainAccount;
    DimensionAttributeValue                 dimensionAttributeValue;
    DimensionAttribute                      dimensionAttribute,
                                            dimensionAttributeSucursal;
       
    mainAccount = mainAccount::findByMainAccountId(_cuenta);
    balanceParaemeters = MainAccountListPageBalanceParameters::construct();
    balance = LedgerBalanceDimAttrValueAmounts::construct();
       
    dimensionAttribute = DimensionAttribute::findByName( "MainAccount");
    dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimensionAttribute.RecId, mainAccount.RecId);
       
    balance.parmAccountingDateRange(balanceParaemeters.getStartDate(), _fechaHasta);
    balance.parmPostingLayer(balanceParaemeters.getPostingLayer());
    balance.parmIncludeOpeningPeriod(balanceParaemeters.getIncludeOperatingPeriods());
    balance.parmIncludeRegularPeriod(balanceParaemeters.getIncludeOperatingPeriods());
    balance.parmIncludeClosingPeriod(balanceParaemeters.getIncludeClosingPeriods());
    balance.parmIncludeClosingPeriodBySystem(balanceParaemeters.getIncludeClosingPeriods());
       
    dimensionAttributeSucursal = DimensionAttribute::findByName( "Sucursal");
    balance.addDimAttrValue(dimensionAttributeSucursal.Recid, _sucursal);
    balance.calculateBalance(dimensionAttributeValue);
       
    return balance.getAccountingCurrencyBalance();
       

}



Post que podrían interesarte:
Saldo de cuenta contable
Saldo de cuenta contable por grupo de artículos


Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 

martes, 27 de octubre de 2015

Particiones en Dynamics Ax 2012 R2

Para dynamics Ax R2 y R3 existe un termino llamado particiones, estas particiones nos permiten compartir información entre empresas que pertenezcan a la misma partición y aislar estos datos del resto de las particiones.

Estas particiones a nivel usuario podemos verlas desde Administración del sistema > Configurar > Particiones.


Nosotros como desarrolladores, lo que debemos saber acerca de las particiones es que con una sentencia de consulta de datos sobre ax no podemos accesar a los datos de otra compañia que se encuentre en distinta partición aunque sea la misma instalación de Ax y la misma base de datos, si alguna vez necesitamos datos de distintas particiones esto debería realizarse por SQL. O si es necesario hacerlo desde ax, aquí un link de cómo realizar una consulta.

En Ax, cada clave y nombre de partición esta almacenada con un identificador. Este identificador es un campo llamado RecId en una tabla y que no es otra cosa que un Int64. Con este identificador Ax guarda el identificador de la partición en todos los registros de todas las tablas para saber a cuál partición pertenece el registro que se ha insertado en la tabla.

Una descripción gráfica de cómo es posible dividir las particiones se encuentra en el siguiente diagrama:

De acuerdo al diagrama, los usuarios de una compañia A tienen cierta configuración de acceso y no podrian entrar a la compañia Z una vez que ya iniciaron Ax. Aunque de otra forma, los usuarios de la compañia A comparten datos de los productos que se comercializan con la compañia B.

Si necesitas saber mas acerca de la arquitectura, link de Microsoft.


Post que podrían interesarte:
Menu de tutorial de desarrollo
Reportes SSRS en Ax



Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 




jueves, 22 de octubre de 2015

Actualizar información de direcciones en clientes por código X++ en Dynamics Ax 2012

En el post anterior les compartí un código para crear clientes ya sean personas o empresas con su dirección e información de contacto, aquí les comparto cómo actualizar estos datos. Espero les sea de utilidad.

static void JobActualizaClientePersona(Args _args)
{
    CustTable                    custTable;
    NumberSeq                    numberSeq;
    Name                         name = 'Jorge Lopez';
 
    DirParty                        dirParty;
    DirPartyPostalAddressView       dirPartyPostalAddressView;
    DirPartyContactInfoView         dirPartyContactInfo;
    ;
 
    ttsBegin;
 
   try
    {
        custTable = custTable::find( "C000020695"); 
       
        select dirPartyPostalAddressView
        where dirPartyPostalAddressView.Party == custtable.Party
        && dirPartyPostalAddressView.IsPrimary == NoYes::Yes;
       
        //DirParty
        //Crea instancia de la clase DirParty a partir de dirPartyPostalAddressView
        //Actualiza dirección principal
        DirParty = DirParty::constructFromPartyRecId(dirPartyPostalAddressView.Party);
 
        dirPartyPostalAddressView.LocationName      = 'Oficina central ';
        dirPartyPostalAddressView.City              = 'Polanco Chapultepec';
        dirPartyPostalAddressView.Street            = 'Presidente Masarik';
        dirPartyPostalAddressView.StreetNumber      = '25';
        dirPartyPostalAddressView.CountryRegionId   = 'MEX'; //necesita ser un país valido
        dirPartyPostalAddressView.State             = '09';  //necesita ser un estado valido
 
        // Llena dirección
        dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
 
        //Actualiza email de información de contacto
        dirPartyContactInfo.clear();
       
        select dirPartyContactInfo
        where dirPartyContactInfo.Party == custtable.Party &&
        dirPartyContactInfo.Type == LogisticsElectronicAddressMethodType::Email;
       
        DirParty = DirParty::constructFromPartyRecId(dirPartyContactInfo.Party);
       
        dirPartyContactInfo.LocationName    = 'Email Jorge Lopez';
        dirPartyContactInfo.Locator         = 'jorge.lopez222@gmail.com';
        dirPartyContactInfo.Type            = LogisticsElectronicAddressMethodType::Email;
        dirPartyContactInfo.IsPrimary       = NoYes::Yes;
 
        dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
       
        //Actualiza telefono de información de contacto
        dirPartyContactInfo.clear();
        select  dirPartyContactInfo
        where dirPartyContactInfo.Party == custtable.Party &&
        dirPartyContactInfo.Type == LogisticsElectronicAddressMethodType::Phone;
       
        DirParty = DirParty::constructFromPartyRecId(dirPartyContactInfo.Party);
       
        dirPartyContactInfo.LocationName    = 'Telefono Jorge';
        dirPartyContactInfo.Locator         = '551291165343';
        dirPartyContactInfo.Type            = LogisticsElectronicAddressMethodType::Phone;
        dirPartyContactInfo.IsPrimary       = NoYes::Yes;
 
        dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
 
        ttsCommit;
       
        info( strFmt("Cliente creado: %1" , custTable.AccountNum));
    }
    catch(Exception::Error)
    {
       ttsAbort;
       throw Exception::Error;
    }

}




Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 

martes, 20 de octubre de 2015

Crear clientes y direcciones por código x++ en Microsoft Dynamics Ax 2012

Aquí cómo crear un cliente con su dirección y un registro de información de contacto como email, mediante código X++.

static void JobCreaClientePersona(Args _args)
{
    CustTable                    custTable;
    NumberSeq                    numberSeq;
    Name                         name = 'Jorge Lopez';
 
    DirParty                        dirParty;
    DirPartyPostalAddressView       dirPartyPostalAddressView;
    DirPartyContactInfoView         dirPartyContactInfo;
    ;
 
    ttsBegin;
    custTable.initValue();
 
   try
    {
       //crea datos del cliente en la CustTable
        numberSeq               = NumberSeq::newGetNum(CustParameters::numRefCustAccount());
        custTable.AccountNum    = numberSeq.num();
        custTable.CustGroup     = '02';
        custTable.Currency      = 'MXP';
        custTable.PaymTermId    = '00';
        custTable.PaymMode      = '01';
 
        //aquí se define si es persona u organización
        custTable.insert(DirPartyType::Person, name);  
 
        //DirParty
        //Crea instancia de la clase DirParty a partir de la entidad de CustTable
        dirParty = DirParty::constructFromCommon(custTable);
 
        dirPartyPostalAddressView.LocationName      = 'Oficina central ';
        dirPartyPostalAddressView.City              = 'Polanco';
        dirPartyPostalAddressView.Street            = 'Presidente Masarik';
        dirPartyPostalAddressView.StreetNumber      = '22';
        dirPartyPostalAddressView.CountryRegionId   = 'MEX'; //necesita ser un país valido
        dirPartyPostalAddressView.State             = '09';  //necesita ser un estado valido
 
        // Llena dirección
        dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
 
        dirPartyContactInfo.LocationName    = 'Email Jorge Lopez';
        dirPartyContactInfo.Locator         = 'jorge.lopez222@gmail.com';
        dirPartyContactInfo.Type            = LogisticsElectronicAddressMethodType::Email;
        dirPartyContactInfo.IsPrimary       = NoYes::Yes;
 
        // Llena dirección de contacto
        dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
 
        ttsCommit;
       
        info( strFmt("Cliente creado: %1" , custTable.AccountNum));
    }
    catch(Exception::Error)
    {
       ttsAbort;
       throw Exception::Error;
    }

}

Post que podrían interesarte:
Capturar errores del infolog mediante código x++
Crear documentos asociados a un registro por código (DocuRef)
Teclas rápidas en Microsoft Dynamics Ax 2012


Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 

viernes, 17 de julio de 2015

Publicar un servicio intermedio .Net para comunicar AIF Dynamics Ax con Java


Me he topado con la no grata sorpresa que para consumir servicios de dynamics Ax 2012 R2 mediante lenguajes distintos a .Net como Java o PHP, la única solución viable es que se ponga un servicio intermedio de .Net que si exponga el wsdl como lo necesitan las distintas plataformas. La razón? que Java o PHP necesitan que se exponga el xsd dentro del wsdl y de momento esto solo lo ofrece .Net, quedando la comunicación como en la figura:

image

Así que comencemos, supongamos que nuestros servicios en Ax están desarrollados y expuestos, esto lo verificamos desde Administración del sistema –> Configuración –> Services and Application Integration Framework –> Puertos de entrada, en esta pantalla podemos observar la url con la que se expone nuestro servicio y que es la url que vamos a referenciar en nuestro “servicio intermedio” de .Net

image

Revisamos que podamos ver en el explorador el wsdl que expone la url de Ax

image

Ahora comenzamos con el servicio intermedio, lo primero es abrir Visual Studio, no hay diferencia si es 2010, 2012 o 2013. Elegimos un nuevo proyecto de tipo WCF –> WCF Web application

image

En las referencias, agregamos nuestra url del servicio de Ax que vamos a consumir en este servicio intermedio. Click derecho sobre el nodo Service References –> Agregar referencia a servicio… Pegamos nuestra url y vemos los servicios, aquí debemos visualizar los métodos disponibles expuestos por nuestro servicio de Ax, con esto ya agregamos nuestro servicio de Ax al servicio intermedio de .Net.

image

Después de esto, necesitamos agregar la lógica que reciba los datos de alguna plataforma externa (Java o Php) para enviarlos hacia Ax. En mi caso, en la interfaz de .Net yo expongo un servicio con dos métodos, en uno recibo datos para crear ordenes de venta y en otro recibo el identificador de una orden de venta y regreso el estatus de la misma.

image

Cada uno con la lógica respectiva. Ahora nos resta publicar el servicio en el IIS para que pueda ser consumido por las distintas plataformas.

image

Elijo que lo quiero publicar en un sistema de archivos para mandarlo al IIS

image

En el Target Location, eliges la carpeta del IIS y el sitio donde quieras publicar, lo puedes publicar dentro de Defatul Web Site en un web application nuevo para tus pruebas o si ya tienes un sitio definido lo eliges.

image

Te regresa la ruta que elegiste a la venta a de perfiles, haces click en el botón “Publicar” y ahora ya abrir el IIS donde vas a ver tu App publicada.

image

Ahora necesitamos verla en el explorador para saber si esta bien publicada. Si le damos click en Browse. De primera instancia nos aparecería este error: “HTTP Error 403.14 – Forbidden, The web server is configured to not list the contents of this directory.”

image      image

Vamos en el IIS a la opción de Directory Exploring y damos doble click para entrar a las propiedades del elemento. Dentro de las propiedades en la barra lateral derecha, esta la opción “Enable”, hacemos click sobre ella.

image
image

Si presionas de nuevo “Browse” se abre el explorador ya con el wsdl listo para consumir!

image

Ahora, este es el wsdl normalito (http://xx.xx.xx.xx/GAELTPortalNet/ServicioNet.svc?wsdl), si lo que buscas es que sea consumido por java, debes poner el xsd en el wsdl, para eso solo cambiamos la ruta agregándole el singlewsdl al final: http://xx.xx.xx.xx/GAELTPortalNet/ServicioNet.svc?singlewsdl

Espero te ayude.

Post que podrían interesarte:
Crear servicio personalizado AIF
Crear documentos asociados a un registro por código (DocuRef)
Teclas rápidas en Microsoft Dynamics Ax 2012


Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 

sábado, 4 de julio de 2015

Rellenar o incluir caracteres en cadenas con strRFix en Dynamics Ax 2012

Muchas veces necesitamos incluir en nuestras cadenas de texto ciertos caracteres porque requerimos que nuestra cadena cumpla con un formato especifico. Por ejemplo, si queremos que un folio en el que no usamos secuencias tenga una norma de 6 dígitos, necesitamos que cuando el usuario introduzca el número "1" se transforme en "00001".

Para esto tenemos la función strRFix, que se usa:

static void mascaraFolios(Args _args)
{
    int                             folioSiguiente;
    DimensionValue                  cedisMascara;
    str                             folioMascara,
                                    cedisSalesLine,
                                    folioOriginal, 
                                    folioFinal;
   
    cedisSalesLine = "13" ;
    folioOriginal = "5" ;

    //Modificación para incluir el cedis en el formato del folio
    //Se requieren 3 dígitos para cedis
    cedisMascara = strRFix(cedisSalesLine, 3 , '0' );
   
    folioSiguiente = str2int(folioOriginal) + 1;
    folioMascara = strRFix(int2str(folioSiguiente), 6, '0');
    folioFinal = cedisMascara + "-" + folioMascara;
   
    info(folioFinal);
}

Y el resultado:


Si quisieras que los ceros los agregara del lado derecho, solo usamos la función strLFix. Por ejemplo:

static void mascaraFolios(Args _args)
{
    int                             folioSiguiente;
    DimensionValue                  cedisMascara;
    str                             folioMascara,
                                    cedisSalesLine,
                                    folioOriginal, 
                                    folioFinal;
   
    cedisSalesLine = "13" ;
    folioOriginal = "5" ;

    //Modificación para incluir el cedis en el formato del folio
    //Se requieren 3 dígitos para cedis
    cedisMascara = strLFix(cedisSalesLine, 3 , '0' );
   
    folioSiguiente = str2int(folioOriginal) + 1;
    folioMascara = strLFix(int2str(folioSiguiente), 6, '0');
    folioFinal = cedisMascara + "-" + folioMascara;
   
    info(folioFinal);
}

Y el resultado:

Post que podrían interesarte:
Capturar errores del infolog mediante código x++
Crear documentos asociados a un registro por código (DocuRef)
Teclas rápidas en Microsoft Dynamics Ax 2012


Y por cierto, acuérdate de darle click a algún anuncio si el post te sirvió de algo. O comenta si quieres saber sobre algún tema en específico.

No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma.