martedì 23 dicembre 2025

D365FFO - Stampare le informazioni sugli indici delle tabelle

Con questo job è possibile recuperare le informazioni sugli indici e sulla tabelle a cui appartengono.

Questo link è stato molto utile:

https://gist.github.com/mazzy-ax/4d4d06ec2fddd885b67527623467aee8

 internal final class LIL_getIndexInfo  
 {  
   public static void main(Args _args)  
   {  
     str60                        packageName,tableName;  
     CLRObject                      packages, models,tables;  
     CLRObject                      packagesEnumerator, modelsEnumerator,tablesEnumerator;  
     str60                        moduleVersion;  
     DictTable                      dictTable;  
     DictIndex                      dictIndex;      
     int                         i;  
     FieldId                       fieldId;  
     TableId                       tableId;  
     DictField                      dictField;  
     boolean                       isUnique;  
     str                         packageDir;  
     Microsoft.Dynamics.AX.Metadata.MetaModel.ModelInfo modelInfo;  
   
     // Recupera i package  
     packages = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetInstalledModuleNames();  
     packagesEnumerator = packages.GetEnumerator();  
       
     // Recupera la directory dei package  
     var environment = Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory::GetApplicationEnvironment();  
     packageDir = environment.get_Aos().get_PackageDirectory();  
   
     // Configurazione provider metadati  
     var runtimeProviderConfiguration = New Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration(packageDir);  
     var metadataProviderFactory = New Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory();  
     Microsoft.Dynamics.AX.Metadata.Providers.IMetadataProvider provider = metadataProviderFactory.CreateRuntimeProvider(runtimeProviderConfiguration);  
     ;  
   
     //loop packages  
     while (packagesEnumerator.moveNext())  
     {  
       packageName = packagesEnumerator.get_Current();  
       models = Microsoft.Dynamics.Ax.Xpp.MetadataSupport::GetModelsInModuleSortedByDisplayName(packageName);  
       modelsEnumerator = models.GetEnumerator();  
         
       //loop models in the package  
       while(modelsEnumerator.MoveNext())  
       {  
         modelInfo = modelsEnumerator.get_Current();  
   
         tables = provider.Tables.ListObjectsForModel(modelInfo.Name);  
         tablesEnumerator = tables.GetEnumerator();  
   
         while(tablesEnumerator.moveNext())  
         {  
           tableName = tablesEnumerator.get_Current();  
   
           if(tableName)  
           {  
             dictTable = new DictTable(tableName2Id(tableName));  
   
             if(dictTable)  
             {  
               for (i = 1; i <= dictTable.indexCnt(); i++)  
               {  
                 dictIndex = new DictIndex(dictTable.id(), dictTable.indexCnt2Id(i));  
   
                 isUnique = !dictIndex.allowDuplicates();  
                   
                 //print table and index info  
                 info(strFmt("Table = %1 | Indice: %2 | Model = %3 | Package = %4 | Modules = %5 | Unique: %6",  
                 tableName,  
                 dictIndex.name(),  
                 modelInfo.Name,  
                 packageName,  
                 dictTable.modules(),  
                 isUnique ? "Yes" : "No"  
                 ));  
               }  
             }  
           }  
         }  
       }  
     }  
   }  
   
 }  

lunedì 24 febbraio 2025

D365FFO - Salvare un file excel nel print archive

 Questo post è interessante perchè mostra come salvare un file nel print archive:

https://www.linkedin.com/pulse/excel-reports-d365-finance-operations-sohan-prasad-kanti/

Possiamo usare questa logica per scrivere una classe (anche batch) per generare un file excel ed effettuare il salvataggio nel print archive:

 private void LIL_GenerateFileAndSaveToPrintArchive()  
 {  
   SalesTable salesTable;  
   
   System.IO.Stream workbookStream = new System.IO.MemoryStream();  
   System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();  
       
   using(var package = new OfficeOpenXml.ExcelPackage(memoryStream))  
   {  
     var worksheets = package.get_Workbook().get_Worksheets();  
     var worksheet = worksheets.Add("Sheet1");  
     var cells = worksheet.get_Cells();  
         
     var currentRow=1 ;  
   
     var cell = cells.get_Item(currentRow,1);  
     cell.set_Value("SalesId");  
   
     while select firstonly10 salesTable  
     {  
       currentRow++;  
       cell= cells.get_Item(currentRow, 1);  
       cell.set_Value(salesTable.SalesId);  
     }  
   
     package.Save();  
   }  
   
   memoryStream.Seek(0,System.IO.SeekOrigin::Begin);  
   
   //salvataggio nel print archive  
   SRSPrintArchiveContract printArchiveContract;  
   
   printArchiveContract = SRSPrintArchiveContract::construct();  
   printArchiveContract.parmExecutionDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));  
   printArchiveContract.parmExecutionTime(DateTimeUtil::getTimeNow(DateTimeUtil::getUserPreferredTimeZone()));  
   printArchiveContract.parmFileName("test.xlsx");  
   printArchiveContract.parmJobDescription("test 01");  
   printArchiveContract.savePrintArchiveDetails(Binary::constructFromMemoryStream(memoryStream).getContainer());  
 }  



giovedì 23 gennaio 2025

AX2012 - D365: remittance address transaction line does not match the remittance address on the payment journal line. TRICKY MESSAGE EASY SOLUTION

In Microsoft Dynamics AX2012 (or in case D365 Dynamics 365 for Finance) , in settlement payment sometime we face to this message (full text): 

"The remittance address on the selected transaction line does not match the remittance address on the selected payment journal line. Change one of the addresses to mark the lines for settlement. Error message while marking transactions for settlement."

 
The message seems high-sounding ! 

Checking in deep transactions data, the main couse is the missmatch between address on the LedgerJounralTrans vs VendTransOpen. It is related to data inheritance. Below the issue loop: 

I) Create a General Journal ; 
II) Add a Vendor/ supplier; 
III) Use the function settlement 
IV) Try to mark a settle open transaction: 

 -> get the error
SOLUTION: To be align the data. The Address / Location between General Journal need to be the same to Open Settlement transaction. 

 Area of focus: We need to includ/add the field "Remittance location" into the form. Using the same address location, we are able to select /mark the transaction.
TECH Details: 
Form:VendOpenTrans 
Table: VendTransOpen 
Form:LedgerJournalTransDaily 
Table: LedgerJournalTrans 
LabelID: @SYS152832 
Field: VendTrans.RemittanceLocation; 
Class: CustVendOpenTransManager - Method: checkRemittanceTransCanBeMarked
Comment: We can face to this issue in Microsoft Dynamics 365 Finance too. 
Enjoy!