domingo, 7 de novembro de 2021

P.U 46 - Erro: Invalid algorithm specified. Ao assinar XML da NF-e

Esse erro começou a surgir após a aplicação do update 46. O core utiliza o algoritimo SHA1 (Secure Hash Algorithm 1), na assinatura do XML da NF-e, no entanto ele já não é seguro e está sendo removido dos produtos Microsoft. Por conta disso, como solução paliativa é necessário abrir uma excessão no escopo da aplicação, para que este algoritmo possa continuar sendo usado. A Microsoft já está a par deste problema. Como Hotfix, adicione a seguinte extension ao seu ambiente:


[ExtensionOf(classStr(EFDocSignXmlDocument_BR))]

internal final class EFDocSignXmlDocument_BR_Extension

{

    public str signDocument(

        KeyVaultCertificateRef _keyVaultCertificateRef,

        DigitalCertificateSubject _certificateSubject,

        XmlElement _xmlDoc,

        str _elementToBeSignedName)

    {

        System.AppContext::SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);

        System.AppContext::SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);


        return next signDocument(_keyVaultCertificateRef, _certificateSubject, _xmlDoc, _elementToBeSignedName);

    }

}

domingo, 28 de março de 2021

Recuperar Label através do ID no D365 F&O

Há uma certa limitação na busca pelo texto das labels Core do D365 F&O. Quando tentamos utilizar a ferramenta própria para isso no Visual Studio, ela simplesmente trava e não trás nenhum resultado. Para contornar isso utilize o job abaixo, ele retornará o texto da label conforme Id passado na URL:

/?mi=SysClassRunner&cls=GetLabelTextById&args=@SYS338946

class GetLabelTextById

{

    /// <summary>

    /// Runs the class with the specified arguments.

    /// </summary>

    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        URLUtility    urlUtility = new URLUtility();

        Str           argsStr    = urlUtility.getQueryParamValue('args');

        Info(Microsoft.Dynamics.Ax.Xpp.LabelHelper::GetLabel(argsStr));

    }

}


terça-feira, 18 de junho de 2019

Prefix não é respeitado quando chamado por AxClasses

Precisei desenvolver uma integração que gera Ordens de Vendas no AX. Para isto utilizei a classe AxSalesTable, chamando o constructValidateInput. O validateInput valida as informações passadas para a classe, no momento em que for tentado executar o save na salesTable.

Abaixo, a maneira a qual o objeto foi instanciado:

axSalesTable = AxSalesTable::constructValidateInput(salesTable);

O meu problema ocorreu no momento em que os dados eram validados, na árvore do Infolog, com a execução em CIL habilitada:

Percebam que o resultado do validateFieldValue da SalesTable, ficou fora do nível correto na árvore. 

Quando executado em X++, a árvore era montada corretamente:


Como neste caso eu não tinha acesso ao validateFieldValue da classe xRecord, sobrescrevi o método na SalesTable, da seguinte forma:

public server boolean validateFieldValue(FieldName _fieldName, int _arrayIndex = 1)
{
    boolean ret;
    str infoOld;
    str infoNew;
    boolean isCLRSession;
    isCLRSession = xSession::isCLRSession();
    if (isCLRSession)
    {
        infoOld = infolog.text(Global::infologLine());
    }
    ret = super(_fieldName, _arrayIndex);

    if (isCLRSession)
    {
        infoNew = infolog.text(Global::infologLine());
        if(infoOld != infoNew)
        {
            infolog.cut(Global::infologLine(),Global::infologLine());
            Global::warning(infoNew);
        }
    }
   
    return ret;
}

Com isso o prefix voltou a ser respeitado no validateFieldValue, quando executado em CIL!

quinta-feira, 18 de outubro de 2018

Como reproduzir a criação do XML da NFe, de uma nota já enviada para a SEFAZ

Para isso basta colocar o seguinte código, no método main de uma classe com a propriedade RunOn como Server, colocar o RecId da FiscalDocument_BR correspondente no parâmetro do método find em seguida pressionar F5:

public server static void Main(Args _args)
{
    EFDocMsgStringStream_BR EFDocMsgStringStream_BR = new EFDocMsgStringStream_BR();
    EFiscalDocumentList_BR EFiscalDocumentList_BR = EFiscalDocumentList_BR::construct();
    EFDocMsgFormat_XmlSubmitV4_BR EFDocMsgFormat_XmlSubmitV4_BR = new EFDocMsgFormat_XmlSubmitV4_BR();
    EFiscalDocument_BR EFiscalDocument_BR;
    ;

    EFiscalDocument_BR = EFiscalDocument_BR::construct(FiscalDocument_BR::find(5640230734,false));
    EFiscalDocumentList_BR.add(EFiscalDocument_BR);
    EFDocMsgFormat_XmlSubmitV4_BR.write(EFDocMsgStringStream_BR, EFiscalDocumentList_BR);
   
    info(EFDocMsgStringStream_BR.toString());
}


quinta-feira, 12 de julho de 2018

Como desabilitar a exclusão de índices SQL, criados fora da AOT - Microsoft Dynamics AX 2012 R3

É sabido que a sincronização do Banco de Dados do AX, exclui todos os índices que por ventura tenham sido criados fora da AOT, ou interface de desenvolvimento do AX.

Navegando pelo LCS encontrei este KB, que torna possível manter estes índices na base:




Ao meu ver, esta é uma forma da Microsoft viabilizar uma maior flexibilidade na criação de índices, já que o Morphex tem algumas limitações.

Como observação, cuidados inerentes a estes índices criados por fora da AOT, devem ser tomados através do SGBD do Sql Server, pois o AX não os enxergará em suas rotinas de manutenção de Banco de Dados!

sábado, 16 de dezembro de 2017

Botão "Editar" da janela de Log de Informações não existe mais. O que fazer? - Microsoft Dynamics 365 FFOEE

Uma das coisas as quais senti falta nas primeiras horas de desenvolvimento na nova versão do ERP Microsoft Dynamics, foi do botão Editar da janela de log de informações do sistema. No Dynamics AX 2012 este botão é uma mão na roda para que precisa saber que evento gerou determinada mensagem. Abaixo uma imagem deste botão:


Era só clicar nele, que o código que originou esta mensagem seria exibido no Morphex.


A maneira que encontrei de contornar tal problema, foi utilizar o método add da classe Info. É por lá que cada mensagem a ser exibida para o usuário, é passada. Basta adicionar um breakpoint  no método e navegar pelo callstack para descobrir a origem da mensagem.



Agora será fácil saber de onde cada mensagem está sendo chamada, no Microsoft Dynamics 365 For Finance and Operation, Enterprise edition!! (belo nome)