UserGroupList userGroupList;
select firstonly RecId from userGroupList where userGroupList.groupId == VendParameters::find().UserGroupId && userGroupList.userId == curUserId(); this.form().design().showNewButton(userGroupList.RecId ? 1 :0);AX-Desire
October 03, 2023
September 30, 2023
X++ code to get GST amount in D365 FO
public Amount getGSTAmount(str type)
{
TaxDocumentComponentTransaction taxDocumentComponentTransaction;
TaxComponentTable_IN taxcomponent;
TaxDocumentComponentTransaction_In taxDocumentComponentTransactionIn;
select sum(TaxAmount) from taxDocumentComponentTransaction
exists join taxDocumentRowTransaction
where taxDocumentRowTransaction.RecId == taxDocumentComponentTransaction.TaxDocumentRowTransactionRecId
&& taxDocumentRowTransaction.Voucher == this.Voucher //Voucher number
&& taxDocumentRowTransaction.InvoiceId == this.CustomerInvoiceNo //Invoice number
&& taxDocumentRowTransaction.TransactionDate == this.CustomerInvoiceDate //Invoice date
exists join taxDocumentComponentTransactionIn
where taxDocumentComponentTransactionIn.TaxDocumentComponnetTransactionRecId == taxDocumentComponentTransaction.RecId
exists join taxcomponent where taxcomponent.RecId == taxDocumentComponentTransactionIn.TaxComponent
&& taxcomponent.TaxType == TaxType_IN::GST
&& taxcomponent.Component == type;
return TaxDocumentComponentTransaction.TaxAmount;
}
September 27, 2023
To Send the email with attachment Using Print Management in D365FO
[ExtensionOf(classStr(SRSPrintDestinationSettings))]
final class SRSPrintDestinationSettings_Extension
{
[SubscribesTo(classStr(SRSPrintDestinationSettingsDelegates), delegateStr(SRSPrintDestinationSettingsDelegates, toSendEmail))]
public static void SRSPrintDestinationSettingsDelegates_toSendEmail(System.Byte[] reportBytes, SrsReportRunPrinter printer, SrsReportDataContract dataContract,Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[] paramArray, EventHandlerResult result)
{
CustParameters parameters = CustParameters::find();
str messageBody;
SysEmailMessageTable message;
LanguageId languageId = CompanyInfo::find().LanguageId;
SRSPrintDestinationSettings printSettings = dataContract.parmPrintSettings();
SysEmailTable sysEmailTable = SysEmailTable::find(parameters.EmailTemplate);
Filename fileName;
SalesConfirmContract contract = new SalesConfirmContract();
SalesTable salesTable;
SalesLine salesLine;
CustConfirmJour custConfirmJour;
Map mappings = new Map(Types::String, Types::String);
ServiceOrderBatchJobService service = new ServiceOrderBatchJobService();
contract = dataContract.parmRdpContract();
custConfirmJour = CustConfirmJour::findRecId(contract.parmRecordId());
select firstonly salesTable
where salesTable.SalesId == custConfirmJour.SalesId;
select firstonly salesLine
where salesLine.SalesId == salesTable.SalesId;
if(!languageId)
{
languageId = sysEmailTable.DefaultLanguage;
}
// Place holders
mappings = service.placeHolders(salesTable,salesLine,'');
message = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);
messageBody = message.Mail;
messageBody = SysLabel::resolveLabels(messageBody, languageId);
messageBody = SysEmailMessage::stringExpand(messageBody, SysEmailTable::htmlEncodeParameters(mappings));
fileName = SysEmailMessage::stringExpand(printSettings.parmFileName(), SysEmailTable::htmlEncodeParameters(mappings));
printSettings.parmEMailContract().parmBody(messageBody);
printSettings.parmFileName(fileName);
}
}
September 26, 2023
Shrink AxDB SQL transaction log - D365 FO
ALTER DATABASE AxDB SET RECOVERY SIMPLE;
USE AxDB; GO CHECKPOINT; GO DBCC SHRINKFILE(AxDBCopy_log, 1000); -- 1000 = 1GB GOUninstall a package - UAT/Prod - D365 FO
You might have to uninstall a deployable package. For example, you might be reorganizing your source code. Alternatively, you no longer require an independent software vendor (ISV) product and haven't renewed the license. Therefore, you must remove the package.
A model is a design-time concept that is part of a package. When a model isn't the only model in a module, you can just remove it from the source code. No other steps are required, because when you deploy the updated module, the old module is overwritten. All overlayer models fall into this category. For more information, see Deleting a model.
Prerequisites
- If any models reference the module that will be removed, the references must be removed from them. For information about how to find the references that must be removed, see Viewing model dependencies.
- Build and deploy any modules that references were removed from.
- All references to and from the modules must be removed before you begin to uninstall the module. To remove all a module's references, add a single class to the model. This class should contain no code. It should contain only a reference to the application platform.
- A Microsoft module cannot be removed. If this is attempted, a validation error will be shown on the package in Lifecycle Services.
- A module cannot be removed if it is part of the AOT deployable package being installed. If you want to remove a module, be sure that it is not part of the package before adding the name to the ModuleToRemove.txt file.
- Create a file that is named ModuleToRemove.txt.
- In the file, put the name of each module that you want to remove on a separate line. Make sure that you've completed the prerequisites for each module that you're removing.
- Create a valid deployable package, and put the ModuleToRemove.txt file in the package\AOSService\Scripts folder.
- Upload the package to the Lifecycle Services asset library. Wait for the asset to finish validation, and review any warnings that are shown on the Asset Details panel on the right side of the page.
- Install the deployable package. For more information about how to install deployable packages, see Apply updates to cloud environments.
- Verify that the package was uninstalled before you complete this procedure in a production environment.
September 20, 2023
Get default site and warehouse of item In D365FO
static void defaultSite(Args _args)
{ InventTable inventTable = inventTable::find('D0001'); InventItemOrderSetupType setupType = InventItemOrderSetupType::Invent; InventDim inventDim; // Default Site inventDim.InventSiteId = inventTable.inventItemOrderSetupMap( setupType).inventSiteId(inventDim.InventSiteId, inventTable); // Default Location inventDim.InventLocationId = inventTable.inventItemOrderSetupMap(setupType, InventDim::findOrCreate(inventDim).InventDimId) .inventLocationId(inventDim.InventLocationId, inventTable, inventDim.InventSiteId); inventDim = InventDim::findOrCreate(inventDim); }September 16, 2023
Setting default values for custom fields - D365 FO
When creating a vendor invoice and you are trying to populate custom fields on table VendInvoiceInfoTable you may find that the following will only work if you are creating a blank invoice and not executing it from the invoice create button on a purchase order
[DataEventHandler(tableStr(VendInvoiceInfoTable), DataEventType::InitializingRecord)]
public static void VendInvoiceInfoTable_onInitializingRecord(Common sender, DataEventArgs e)
{
VendInvoiceInfoTable vendInvoiceInfoTable = sender as VendInvoiceInfoTable;
vendInvoiceInfoTable.CustomField VendParameters::find().DefaultCustomField;
}
This is due to the class PurchFormletterParmDataInvoice.createInvoiceHeaderFromTempTable()
which called .skipEvents(true), skipDataMethods(true), .skipDatabaseLog(true) and calls a query::insert_recordset() because of this none of the default events will get triggered.
In order to properly populate customfields on a blank vendor invoice or creating once from a purchase order the following will need to be done via extensions and CoC.
1. Add custom fields to VendInvoiceInfoTable
2. Add custom fields to VendInvoiceInfoTableTmp (name and types need to match what was created on VendInvoiceInfoTable)
1. We have to add it to this table because on PurchFormLetterParmDataInvoice.insertParmTable() it calls a buf2buf command which loops through the field list.
3. Create extension class of table VendInvoiceInfoTable and apply a CoC of defaultRow method which will populate the value onto both the regular and tmp instance of VendInvoiceInfoTable however it will not save to the database unless the remaining steps are completed
/// <summary>
/// Default values for a vendor invoice header from a purchase order
/// </summary>
[ExtensionOf(tableStr(VendInvoiceInfoTable))]
final class InvoiceModsVendInvoiceInfoTable_Extension
{
/// <summary>
/// COC table method defaultRow which resets default valies
/// </summary>
/// <param name = "_purchTable">PurchTable</param>
/// <param name = "_ledgerJournalTrans">LedgerJournalTrans</param>
/// <param name = "_resetFieldState">Reset field state</param>
public void defaultRow(PurchTable _purchTable, LedgerJournalTrans _ledgerJournalTrans, boolean _resetFieldState)
{
CustomEDTType defaultCustomField;
next defaultRow(_purchTable,_ledgerJournalTrans,_resetFieldState);
//find the default custom field from vend parms
defaultCustomField = VendParameters::find().DefaultCustomField;
//save the default invoice type to the header which will get copied to VendInvoiceInfoTableTmp and then back to the main table due to PurchFormLetterParmDataInvoice.createInvoiceHeaderFromTempTable
this.CustomField = defaultCustomField;
}
}
4. Create extension class of PurchFormLletterParmDataInvoice and apply a CoC to buildCreateInvoiceHeaderFromTempTableFieldQuery and buildCreateInvoiceHeaderFromTempTableFieldMap because the method PurchFormletterParmDataInvoice.createInvoiceHeaderFromTempTable() creates a dynamic map of the fields to copy from the temp table into the main table
[ExtensionOf(classStr(PurchFormletterParmDataInvoice))]
final class InvoiceModsPurchFormletterParmDataInvoice_Extension
{
/// <summary>
/// COC method that adds our custom field to the Field Query selection from the temp table
/// </summary>
/// <param name = "_qbdsVendInvoiceInfoTableTmp">VendInvoiceInfoTableTmp</param>
protected void buildCreateInvoiceHeaderFromTempTableFieldQuery(QueryBuildDataSource _qbdsVendInvoiceInfoTableTmp)
{
next buildCreateInvoiceHeaderFromTempTableFieldQuery(_qbdsVendInvoiceInfoTableTmp);
//add custom selection field
_qbdsVendInvoiceInfoTableTmp.addSelectionField(fieldNum(VendInvoiceInfoTableTmp, CustomField));
}
/// <summary>
/// COC method thats adds our custom field to the dynamic field map against the main table. Which will get copied from the selection query
/// </summary>
/// <param name = "_qbdsVendInvoiceInfoTableTmp">VendInvoiceInfoTableTmp</param>
/// <returns>Modified dynamic map to insert into the db</returns>
protected Map buildCreateInvoiceHeaderFromTempTableFieldMap(QueryBuildDataSource _qbdsVendInvoiceInfoTableTmp)
{
var targetToSourceMap = next buildCreateInvoiceHeaderFromTempTableFieldMap(_qbdsVendInvoiceInfoTableTmp);
targetToSourceMap.insert(fieldStr(VendInvoiceInfoTable, CustomField), [_qbdsVendInvoiceInfoTableTmp.uniqueId(), fieldStr(VendInvoiceInfoTableTmp, CustomField)]);
return targetToSourceMap;
}
}
By applying our populate method to the defaultRow() method this will also trigger the value to populated on a blank vendor invoice once a vendor account is selected.