Buscar en este blog

martes, 20 de marzo de 2018

Module 'xxx' has invalid reference to module...model store is in broken state. Microfost Dynamics 365FO


En uno de mis modelos de pruebas, hice una referencia circular, que no dejaba volver a abrir el formulario de modelos desde VS y mostraba el error siguiente incluso al tratar de crear objetos nuevos en un proyecto:


Module 'xxx' has invalid reference to module 'xxx' that can cause circular dependecies. This is an indication that model store is in broken state.



La solución fue abrir el notepad con permisos de admin y en la ruta de los packages locales, buscar el modelo que estaba causando error (GRWYCFormsLab) y borrarle la referencia al modelo GRWYCAssetFix.

Guardé el archivo, cerre visual studio, volví a abrir y listo!!!!







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. 

lunes, 25 de diciembre de 2017

Como validar que una cuenta exista en una estructura contable en Microsoft Dynamics Ax 2012


Para saber si una cuenta existe o no en una estructura contable podemos usar la clase DimensionHierarchy y el método getAccountStructure, si este método nos devuelve un valor quiere decir que si existe en alguna estructura contable configurada en Ax, aquí el siguiente código:


static void Job42(Args _args)
{
    LedgerRecId         ledgerRecId;
    DimensionHierarchyId  dimensionHierarchyId;
    MainAccount         mainAccount;
    ledgerRecId = Ledger::current();

    mainAccount = mainAccount::findByMainAccountId("001000");
    dimensionHierarchyId = DimensionHierarchy::getAccountStructure(mainAccount.RecId, ledgerRecId);
   
    if(!dimensionHierarchyId)
    {
        throw error(strFmt("@SYS4009834", MainAccount::find(mainAccount.RecId).MainAccountId));
    }
    else
    {
        info(strFmt("La cuenta %1 si existe en la estructura %2.", MainAccount::find(mainAccount.RecId).MainAccountId, DimensionHierarchy::find(dimensionHierarchyId).Name));

    }




Post relacionados:
Crear una entrada de presupuesto por código - Microsoft Dynamics Ax 2012
The request failed with HTTP status 401: Unauthorized. Enterprise Portal Dynamics Ax 2012
Usuario actual, nombre de usuario, moneda de la empresa Dynamics Ax 2012


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. 

domingo, 8 de octubre de 2017

Crear una entrada de presupuesto por código - Microsoft Dynamics Ax 2012

Aquí como hacer una entrada de presupuesto:

static void createBudgetHeaderAndLine(Args _args)
{
    BudgetTransactionHeader         header;
    BudgetTransactionLine           line;

    AxBudgetTransactionHeader       axHeader;
    AxBudgetTransactionLine         axLine;

    header.initValue();
    header.Date = 18\09\2017;
    header.BudgetModelId = PurchParameters::find().GRWModelId;
    header.BudgetTransactionCode = BudgetTransactionCode::findByBudgetTransactionCode(PurchParameters::find().GRWBudgetTransactionCode).RecId;

    axHeader = AxBudgetTransactionHeader::newBudgetTransactionHeader(header);
    axHeader.save();

    axLine = AxBudgetTransactionLine::construct();
    axLine.parmBudgetTransactionHeader(axHeader.parmRecId());
    axLine.parmLedgerDimension(5637146826);
    axLine.parmDate(18\09\2017);
    axLine.parmTransactionCurrencyAmount(30);
    axLine.parmBudgetType(BudgetType::Expense);
    axLine.parmTransactionCurrency("MXN");
    axLine.save();

    info(strFmt("Entrada de presupuesto creada: %1", header.TransactionNumber));

}

Y en Ax se ve algo como esto:




Post relacionados:
Autoliquidación de transacciones (Auto settlement) por código X++ - Dynamics Ax 2012
Validar si existe un archivo y la extensión del mismo por código - Dynamics Ax 2012
Lista de remisiones asociadas a una factura por código X++ en Dynamics Ax 2012


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, 6 de octubre de 2017

Autoliquidación de transacciones (Auto settlement) por código X++ - Dynamics Ax 2012

Para hacer la liquidación en automático de dos transacciones podemos usar el siguiente código:

static void autoSettlementExWill(Args _args)
{
    VendTrans                   vendTransFrom, vendTransTO;
    VendTransOpen               vendTransOpenFrom, vendTransOpenTo;
    CustVendOpenTransManager    SettleManager;
    Common                      originator;
    boolean                     settled;

    try
    {
        vendTransFrom = vendTrans::find(5637155127);
        vendTransTO = vendTrans::find(5637155128);
               
        //Revisando que no esten erradas las transacciones
        if(!vendTransFrom.Closed && !vendTransTo.Closed)
        {
            select firstonly vendTransOpenFrom
                where vendTransOpenFrom.RefRecId == vendTransFrom.RecId
                && vendTransOpenFrom.AccountNum == vendTransFrom.AccountNum;

            select firstonly vendTransOpenTo
                where vendTransOpenTo.RefRecId == vendTransTo.RecId
                && vendTransOpenTo.AccountNum == vendTransTo.AccountNum;

            originator = vendTransFrom.vendInvoiceJour().vendTable_InvoiceAccount();
            SettleManager = custVendOpenTransManager::construct(originator);  //en el originator solo hay custtable y vendtable en el swicht
            SettleManager.updateTransMarked(vendTransOpenFrom, true);
            SettleManager.updateTransMarked(vendTransOpenTo, true);
            settled = SettleManager.settleMarkedTrans();
           
            info(strFmt("Asiento liquidado: %1, con %2", vendTransFrom.Voucher, vendTransTO.Voucher));
        }
        else
            warning(strFmt("Las transacciones de los asientos: %1 y %2, no estan abiertas.", vendTransFrom.Voucher, vendTransTO.Voucher));
    }
    catch
    {
        error(strFmt("No fue posible liquidar las transacciones de proveedor. Asientos no liquidados: %1, con %2",
        vendTransFrom.Voucher, vendTransTO.Voucher));
    }

}




Post relacionados:
Crear y postear un LedgerVoucher en Ax 2012
Usuario actual, nombre de usuario, moneda de la empresa Dynamics Ax 2012
Lookup para dimensiones financieras personalizadas - Microsoft Dynamics Ax 2012 R2



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, 12 de septiembre de 2017

Validar si existe un archivo y la extensión del mismo por código - Dynamics Ax 2012


Cuando se requiere validar si un archivo aún existe en una ruta y/o validar el tipo de archivo de acuerdo a la extensión, se puede usar dos opciones. Con una de ellas se debe tener cuidado porque no funciona si se requiere para un proceso batch.


static void ValidateFile(Args _args)
{
Contracts contract;
boolean existe;
System.IO.FileInfo fileInfo;
container datosArchivo;
str extArchivo;

//se busca un registro de una tabla que en uno de sus campos contiene un path completo del tipo c:\\carpeta1\archivo.docx
contract = Contracts::find("CONTRATO 050717");

//Opción 1: del lado del server, si funciona en procesos batch
new InteropPermission(InteropKind::ClrInterop).assert();
fileInfo = new System.IO.FileInfo(contract.AttachmentPath);
extArchivo = fileInfo.get_Extension();
existe = fileInfo.get_Exists();
CodeAccessPermission::revertAssert();

if (existe)
{
  info("si existe");

  //Valida si es un word
  if(strStartsWith(extArchivo, ".do"))
    info("si es doc");
  else
    info("no es doc");
}
else
{
  info("no existe");
}

//Opción 2 - del lado del cliente, no funciona bajo procesos batch
if (WinAPI::fileExists(itsContract.AttachmentPath))
{
  info("si existe 2");

  //Valida si es un word
  new InteropPermission(InteropKind::ClrInterop).assert();
  datosArchivo = Global::fileNameSplit(contract.AttachmentPath);
  CodeAccessPermission::revertAssert();

  if(strStartsWith(conPeek(datosArchivo, 3), ".do"))
    info("si es doc 2");
  else
    info("no es doc 2");
}
else
{
  info("no existe 2");
}

}



Post relacionados:
Registrar diario de producción por código, Dynamics Ax 2009, X++
Métodos display y métodos edit en un datasource o tablas temporales, Dynamics Ax 2012
Imprimir factura electrónica (México) a partir de una CustInvoiceJour por código - Dynamics Ax 2012



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.