March 27, 2015
March 26, 2015
X++ code to print New Line
static void NewLine_Str(Args _args)
{
TextBuffer t;
;
t = new TextBuffer();
t.setText("Hai.Welcome");
while (t.nextToken(false,'.'))
{
info(t.token());
}
}
March 19, 2015
X++ code to get Financial dimension for a purchase order in Ax 2012
static void ShowVendDefaultDimensions(Args _args)
{
PurchTable PurchTable;
PurchLine PurchLine;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItem dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Common dimensionValueEntity;
;
// Find our supplier
PurchLine = PurchLine::find('000093');
// Find the dimension value set that the vendor points to (for specifying the
// 'default' dimensions). This table is used as a sort of 'header' that the
// value set items (DimensionAttributeValueSetItem) records belong to.
dimAttrValueSet = DimensionAttributeValueSet::find(PurchLine.DefaultDimension);
// Find all of the 'value set items' linked against the 'value set'
while select dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == dimAttrValueSet.RecId
{
// Find the dimension 'value' (DimensionAttributeValue) that the set item points to.
dimAttrValue = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
// Find the underlying attribute.
dimAttr = DimensionAttribute::find(dimAttrValue.DimensionAttribute);
// Use the helper class to obtain a reference to the underlying entity (can be anything)
dimensionValueEntity = DimensionDefaultingControllerBase::findBackingEntityInstance(
curext(),
dimAttr,
dimAttrValue.EntityInstance);
info(dimAttr.Name + ' ' + dimAttrValue.getValue());
}
}
{
PurchTable PurchTable;
PurchLine PurchLine;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItem dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Common dimensionValueEntity;
;
// Find our supplier
PurchLine = PurchLine::find('000093');
// Find the dimension value set that the vendor points to (for specifying the
// 'default' dimensions). This table is used as a sort of 'header' that the
// value set items (DimensionAttributeValueSetItem) records belong to.
dimAttrValueSet = DimensionAttributeValueSet::find(PurchLine.DefaultDimension);
// Find all of the 'value set items' linked against the 'value set'
while select dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == dimAttrValueSet.RecId
{
// Find the dimension 'value' (DimensionAttributeValue) that the set item points to.
dimAttrValue = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
// Find the underlying attribute.
dimAttr = DimensionAttribute::find(dimAttrValue.DimensionAttribute);
// Use the helper class to obtain a reference to the underlying entity (can be anything)
dimensionValueEntity = DimensionDefaultingControllerBase::findBackingEntityInstance(
curext(),
dimAttr,
dimAttrValue.EntityInstance);
info(dimAttr.Name + ' ' + dimAttrValue.getValue());
}
}
X++ code to convert Number to Text
static void numtotxt(Args _args)
{
real i;
str val;
;
i= 3241.20;
val = numeralsToTxt_EN(i);
val = substr(val,5, strlen(val)-4);
info(strFmt("%1",numeralsToTxt(i)));
info(strFmt("%1",numeralsToTxt_EN(i)));
info(strFmt("%1",val));
}
{
real i;
str val;
;
i= 3241.20;
val = numeralsToTxt_EN(i);
val = substr(val,5, strlen(val)-4);
info(strFmt("%1",numeralsToTxt(i)));
info(strFmt("%1",numeralsToTxt_EN(i)));
info(strFmt("%1",val));
}
X++ code to mail Report in AX 2012
public void EmailReport(Args _args)
{
SrsReportRunController controller = new SrsReportRunController();
SRSPrintDestinationSettings printSettings;
SrsReportEMailDataContract emailContract;
// set report name
controller.parmReportName(ssrsReportStr(CustTransList, Report));
// create email contract
emailContract = new SrsReportEMailDataContract();
// fill in the email contract details
emailContract.parmAttachmentFileFormat(SRSReportFileFormat::PDF);
emailContract.parmSubject("Customer Transaction Report");
emailContract.parmTo("shwethakodli@outlook.com");
// get print settings from contract
printSettings = controller.parmReportContract().parmPrintSettings();
// update print settings with email contract and use pdf format in the attachment
printSettings.printMediumType(SRSPrintMediumType::Email);
printSettings.parmEMailContract(emailContract);
printSettings.fileFormat(SRSReportFileFormat::PDF);
// suppress the parameter dialog
controller.parmShowDialog(false);
// start operation
controller.startOperation();
info("Report Mailed");
}
{
SrsReportRunController controller = new SrsReportRunController();
SRSPrintDestinationSettings printSettings;
SrsReportEMailDataContract emailContract;
// set report name
controller.parmReportName(ssrsReportStr(CustTransList, Report));
// create email contract
emailContract = new SrsReportEMailDataContract();
// fill in the email contract details
emailContract.parmAttachmentFileFormat(SRSReportFileFormat::PDF);
emailContract.parmSubject("Customer Transaction Report");
emailContract.parmTo("shwethakodli@outlook.com");
// get print settings from contract
printSettings = controller.parmReportContract().parmPrintSettings();
// update print settings with email contract and use pdf format in the attachment
printSettings.printMediumType(SRSPrintMediumType::Email);
printSettings.parmEMailContract(emailContract);
printSettings.fileFormat(SRSReportFileFormat::PDF);
// suppress the parameter dialog
controller.parmShowDialog(false);
// start operation
controller.startOperation();
info("Report Mailed");
}
RecordInsertList - Example
static void RecordInsertList_example(Args _args)
{
RecordInsertList recordins;
CustTable cust;
recordins=new RecordInsertList(tablenum(CustTable));
cust.AccountNum='13134';
cust.CustGroup='80';
cust.AccountNum = '12345';
cust.CustGroup = '80';
recordins.add(cust);
recordins.insertDatabase();
info(strfmt("Record inserted"));
}
{
RecordInsertList recordins;
CustTable cust;
recordins=new RecordInsertList(tablenum(CustTable));
cust.AccountNum='13134';
cust.CustGroup='80';
cust.AccountNum = '12345';
cust.CustGroup = '80';
recordins.add(cust);
recordins.insertDatabase();
info(strfmt("Record inserted"));
}
X++ code to send mail using outlook
static void sendEmailThroughOutlook(Args args)
{
SmmOutlookEMail smmOutlookEMail = new SmmOutlookEMail();
Object smmSendEmail;
;
args = new Args();
args.name(formstr(smmSendEmail));
args.caller(smmOutlookEMail);
smmSendEmail = classfactory.formRunClass(args);
if (smmSendEmail)
{
smmSendEmail.init();
smmSendEmail.setEmailTos("Test123@gmail.com");
smmSendEmail.setEmailSubject("Test");
smmSendEmail.run();
smmSendEmail.refreshControl();
smmSendEmail.wait();
}
info("done");
}
{
SmmOutlookEMail smmOutlookEMail = new SmmOutlookEMail();
Object smmSendEmail;
;
args = new Args();
args.name(formstr(smmSendEmail));
args.caller(smmOutlookEMail);
smmSendEmail = classfactory.formRunClass(args);
if (smmSendEmail)
{
smmSendEmail.init();
smmSendEmail.setEmailTos("Test123@gmail.com");
smmSendEmail.setEmailSubject("Test");
smmSendEmail.run();
smmSendEmail.refreshControl();
smmSendEmail.wait();
}
info("done");
}
X++ code to get Mandatory fileds from a Table
static void MandatoryFieldOfAOTTable(Args _args)
{
SysDictTable dTable;
SysDictField dField;
Counter counter;
;
dTable = new SysDictTable(tablenum(Ledger));
for(counter =1; counter<= dTable.fieldCnt();counter++)
{
dField = new SysDictField(dTable.id(),dTable.fieldCnt2Id(counter));
if(dField.mandatory())
info(dField.name());
}
}
{
SysDictTable dTable;
SysDictField dField;
Counter counter;
;
dTable = new SysDictTable(tablenum(Ledger));
for(counter =1; counter<= dTable.fieldCnt();counter++)
{
dField = new SysDictField(dTable.id(),dTable.fieldCnt2Id(counter));
if(dField.mandatory())
info(dField.name());
}
}
X++ code to run SSRS report in AX 2012
public static void runSSRSReport()
{
int i;
SrsReportRunController controller;
controller = new SrsReportRunController();
controller.parmLoadFromSysLastValue(false);
for(i=0;i<=3;i++)
{
controller.parmReportName("CustTransList.Report");
controller.parmReportContract().parmPrintSettings().landscape(true);
controller.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::Screen);
controller.parmExecutionMode(SysOperationExecutionMode::ReliableAsynchronous);
controller.runReport();
}
}
{
int i;
SrsReportRunController controller;
controller = new SrsReportRunController();
controller.parmLoadFromSysLastValue(false);
for(i=0;i<=3;i++)
{
controller.parmReportName("CustTransList.Report");
controller.parmReportContract().parmPrintSettings().landscape(true);
controller.parmReportContract().parmPrintSettings().printMediumType(SRSPrintMediumType::Screen);
controller.parmExecutionMode(SysOperationExecutionMode::ReliableAsynchronous);
controller.runReport();
}
}
X++ code to get files from a Filepath in AX 2009
static void PathGetting(Args _args)
{
FilePath sFilePath;
System.IO.DirectoryInfo di;
System.IO.FileInfo[] fis;
System.IO.FileInfo fi;
int i;
int l;
;
sFilePath="C:\\temp\\test\\";
di = new System.IO.DirectoryInfo(sFilePath);
fis = di.GetFiles();
l = fis.get_Length();
for (i = 0; i < l; i++)
{
fi = fis.GetValue(i);
info(fi.get_FullName());
}
}
{
FilePath sFilePath;
System.IO.DirectoryInfo di;
System.IO.FileInfo[] fis;
System.IO.FileInfo fi;
int i;
int l;
;
sFilePath="C:\\temp\\test\\";
di = new System.IO.DirectoryInfo(sFilePath);
fis = di.GetFiles();
l = fis.get_Length();
for (i = 0; i < l; i++)
{
fi = fis.GetValue(i);
info(fi.get_FullName());
}
}
X++ code to create a new form in AX 2012
static void comboBox(Args _args)
{
Dialog dialog = new Dialog();
DialogField dialogField;
FormBuildComboBoxControl formComboBoxControl;
int i;
;
dialogField = dialog.addField(EnumStr(YearEnum));
formComboBoxControl=dialogField.control();
formComboBoxControl.enumType(0);
formComboBoxControl.label("Year");
formComboBoxControl.items(11);
for(i=0;i<=10;i++)
{
formComboBoxControl.item(i+1);
formComboBoxControl.text(int2str(year(systemDateGet())-i));
}
dialog.run();
}
{
Dialog dialog = new Dialog();
DialogField dialogField;
FormBuildComboBoxControl formComboBoxControl;
int i;
;
dialogField = dialog.addField(EnumStr(YearEnum));
formComboBoxControl=dialogField.control();
formComboBoxControl.enumType(0);
formComboBoxControl.label("Year");
formComboBoxControl.items(11);
for(i=0;i<=10;i++)
{
formComboBoxControl.item(i+1);
formComboBoxControl.text(int2str(year(systemDateGet())-i));
}
dialog.run();
}
X++ code to create ComboBox
static void comboBox(Args _args)
{
Dialog dialog = new Dialog();
DialogField dialogField;
FormBuildComboBoxControl formComboBoxControl;
int i;
;
dialogField = dialog.addField(EnumStr(YearEnum));
formComboBoxControl=dialogField.control();
formComboBoxControl.enumType(0);
formComboBoxControl.label("Year");
formComboBoxControl.items(11);
for(i=0;i<=10;i++)
{
formComboBoxControl.item(i+1);
formComboBoxControl.text(int2str(year(systemDateGet())-i));
}
dialog.run();
}
{
Dialog dialog = new Dialog();
DialogField dialogField;
FormBuildComboBoxControl formComboBoxControl;
int i;
;
dialogField = dialog.addField(EnumStr(YearEnum));
formComboBoxControl=dialogField.control();
formComboBoxControl.enumType(0);
formComboBoxControl.label("Year");
formComboBoxControl.items(11);
for(i=0;i<=10;i++)
{
formComboBoxControl.item(i+1);
formComboBoxControl.text(int2str(year(systemDateGet())-i));
}
dialog.run();
}
X++ code to add Enum in AX 2012
static void addEnumvalue(Args _args)
{
#AOT
TreeNode treeNodeEnum;
treeNodeEnum = TreeNode::findNode(#BaseEnumsPath);
treeNodeEnum = treeNodeEnum.AOTfindChild('YearEnum');
treeNodeEnum.AOTadd('Test');
treeNodeEnum.AOTsave();
}
{
#AOT
TreeNode treeNodeEnum;
treeNodeEnum = TreeNode::findNode(#BaseEnumsPath);
treeNodeEnum = treeNodeEnum.AOTfindChild('YearEnum');
treeNodeEnum.AOTadd('Test');
treeNodeEnum.AOTsave();
}
X++ code to create Excel file in AX 2009
static void CreateExcelDocument (Args _args)
{
SysExcelApplication xlsApplication;
SysExcelWorkBooks xlsWorkBookCollection;
SysExcelWorkBook xlsWorkBook;
SysExcelWorkSheets xlsWorkSheetCollection;
SysExcelWorkSheet xlsWorkSheet;
SysExcelRange xlsRange;
CustTable custTable;
int row = 1;
str fileName;
;
// Name of the Excel document.
fileName = "C:\\test.xslx";
// Excel open and initialize.
xlsApplication = SysExcelApplication:: construct ();
xlsApplication.visible (true);
// Create an Excel Worksheet produce.
xlsWorkBookCollection = xlsApplication.workbooks();
xlsWorkBook = xlsWorkBookCollection.add();
xlsWorkSheetCollection = xlsWorkBook.worksheets();
xlsWorkSheet = xlsWorkSheetCollection.itemFromNum (1);
// Write to the worksheet cells headings.
xlsWorkSheet.cells (). item (row, 1). value ('Account Number');
xlsWorkSheet.cells (). item (row,2). value ('name');
row ++;
// Excel Worksheet with data fill / (Excel cells fill).
while select custTable
{
xlsWorkSheet.cells (). item (row, 1). value (custTable.AccountNum);
xlsWorkSheet.cells (). item (row, 2). value (custTable.Name);
row ++;
}
// Check whether the document already exists.
if (WINAPI:: fileExists (fileName))
{
Winapi:: DeleteFile (fileName);
}
// Save Excel document.
xlsWorkbook.saveAs(fileName);
// Close Excel.
xlsApplication.quit ();
xlsApplication.finalize ();
}
{
SysExcelApplication xlsApplication;
SysExcelWorkBooks xlsWorkBookCollection;
SysExcelWorkBook xlsWorkBook;
SysExcelWorkSheets xlsWorkSheetCollection;
SysExcelWorkSheet xlsWorkSheet;
SysExcelRange xlsRange;
CustTable custTable;
int row = 1;
str fileName;
;
// Name of the Excel document.
fileName = "C:\\test.xslx";
// Excel open and initialize.
xlsApplication = SysExcelApplication:: construct ();
xlsApplication.visible (true);
// Create an Excel Worksheet produce.
xlsWorkBookCollection = xlsApplication.workbooks();
xlsWorkBook = xlsWorkBookCollection.add();
xlsWorkSheetCollection = xlsWorkBook.worksheets();
xlsWorkSheet = xlsWorkSheetCollection.itemFromNum (1);
// Write to the worksheet cells headings.
xlsWorkSheet.cells (). item (row, 1). value ('Account Number');
xlsWorkSheet.cells (). item (row,2). value ('name');
row ++;
// Excel Worksheet with data fill / (Excel cells fill).
while select custTable
{
xlsWorkSheet.cells (). item (row, 1). value (custTable.AccountNum);
xlsWorkSheet.cells (). item (row, 2). value (custTable.Name);
row ++;
}
// Check whether the document already exists.
if (WINAPI:: fileExists (fileName))
{
Winapi:: DeleteFile (fileName);
}
// Save Excel document.
xlsWorkbook.saveAs(fileName);
// Close Excel.
xlsApplication.quit ();
xlsApplication.finalize ();
}
X++ code to get AssestId in AX 2009
static void assetIdCheck(Args _args)
{
LedgerTable ledgerTable;
LedgerTrans ledgerTrans;
AssetTrans assetTrans;
;
select AssetId from assetTrans
join ledgerTrans join ledgerTable
where assetTrans.Voucher == ledgerTrans.Voucher && ledgertrans.AccountNum == '110110';
info (assetTrans.AssetId);
info (ledgerTrans.AccountNum);
}
{
LedgerTable ledgerTable;
LedgerTrans ledgerTrans;
AssetTrans assetTrans;
;
select AssetId from assetTrans
join ledgerTrans join ledgerTable
where assetTrans.Voucher == ledgerTrans.Voucher && ledgertrans.AccountNum == '110110';
info (assetTrans.AssetId);
info (ledgerTrans.AccountNum);
}
X++ code for Creating and invoicing Sales order in AX 2012
static void SOAutoConfirmAndInvoice(Args _args)
{
SalesTable salesTable;
SalesLine salesLine;
CustTable custTable= CustTable::find("US-101");
AxSalesTable axsalesTable;
AxSalesLine axSalesLine;
SalesFormLetter salesFormLetter;
;
//Create Sales order
salesTable.initFromCustTable();
axsalesTable = AxSalesTable::newSalesTable(salesTable);
axsalesTable.parmCustAccount("US-004");
axsalesTable.parmSalesType(SalesType::Sales);
axsalesTable.parmDocumentStatus(DocumentStatus::Confirmation);
axsalesTable.parmDeliveryDate(str2Date("03/18/2015",213));
axsalesTable.parmSalesStatus(SalesStatus::Backorder);
axsalesTable.doSave();
salesLine.initFromSalesTable(salesTable);
axSalesLine = AxSalesLine::newSalesLine(salesLine);
axSalesLine.parmItemId("T0001");
axSalesLine.parmInventDimId("000458");
axSalesLine.parmCurrencyCode("USD");
axSalesLine.parmSalesQty(2);
axSalesLine.parmSalesPrice(10.00);
axSalesLine.doSave();
//SO confirmation
salesTable = axSalesTable.salesTable(salesTable);
salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);
salesFormLetter.update(salesTable);
// SO invoicing
salesFormLetter = salesFormLetter::construct(DocumentStatus::Invoice);
salesFormLetter.update(salesTable);
info(strFmt("Sales order %1 invoiced",salesTable.SalesId));
}
{
SalesTable salesTable;
SalesLine salesLine;
CustTable custTable= CustTable::find("US-101");
AxSalesTable axsalesTable;
AxSalesLine axSalesLine;
SalesFormLetter salesFormLetter;
;
//Create Sales order
salesTable.initFromCustTable();
axsalesTable = AxSalesTable::newSalesTable(salesTable);
axsalesTable.parmCustAccount("US-004");
axsalesTable.parmSalesType(SalesType::Sales);
axsalesTable.parmDocumentStatus(DocumentStatus::Confirmation);
axsalesTable.parmDeliveryDate(str2Date("03/18/2015",213));
axsalesTable.parmSalesStatus(SalesStatus::Backorder);
axsalesTable.doSave();
salesLine.initFromSalesTable(salesTable);
axSalesLine = AxSalesLine::newSalesLine(salesLine);
axSalesLine.parmItemId("T0001");
axSalesLine.parmInventDimId("000458");
axSalesLine.parmCurrencyCode("USD");
axSalesLine.parmSalesQty(2);
axSalesLine.parmSalesPrice(10.00);
axSalesLine.doSave();
//SO confirmation
salesTable = axSalesTable.salesTable(salesTable);
salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);
salesFormLetter.update(salesTable);
// SO invoicing
salesFormLetter = salesFormLetter::construct(DocumentStatus::Invoice);
salesFormLetter.update(salesTable);
info(strFmt("Sales order %1 invoiced",salesTable.SalesId));
}
X++ code for creating and invoicing Purchase order in AX 2012
static void POAutoConfirmAndInvoice(Args _args)
{
PurchTable purchTable;
PurchLine purchLine;
VendTable vendTable = VendTable::find("US-101");
AxPurchTable axPurchTable;
AxPurchLine axPurchLine;
PurchFormLetter purchFormLetter;
;
//Create Purchase order
purchTable.initFromVendTable(vendTable);
axPurchTable = axPurchTable::newPurchTable(purchTable);
axPurchTable.parmPurchaseType(PurchaseType::Purch);
axPurchTable.parmDocumentStatus(DocumentStatus::PurchaseOrder);
axPurchTable.parmDeliveryDate(str2date("03/18/2015",213));
axPurchTable.parmAccountingDate(str2date("03/18/2015",213));
axPurchTable.parmPurchStatus(PurchStatus::Backorder);
axPurchTable.doSave();
purchLine.initFromPurchTable(purchTable);
axPurchLine = AxPurchLine::newPurchLine(purchLine);
axpurchLine.parmItemId("T0001");
axpurchLine.parmInventDimId('000458');
axPurchLine.parmPurchQty(10);
axPurchLine.parmPurchPrice(100);
axPurchLine.doSave();
//PO confirmation
purchTable = axPurchTable.purchTable();
purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);
purchFormLetter.update(purchTable, strFmt("Inv_%1", purchTable.PurchId));
// PO invoicing
purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
purchFormLetter.update(purchTable, strFmt("Inv_%1", purchTable.PurchId));
info(strFmt("purchase order %1 invoiced",purchTable.PurchId));
}
X++ code to find all the reports with datasources innerjoined 1:1
static void FindAllReports(Args _args)
{
#AOT
Report report;
TreeNode treeNode = TreeNode::findNode(#ReportsPath);
TreeNodeIterator iterator = treeNode.AOTiterator();
QueryBuildDataSource qbds;
boolean find1nInnerJoin(QueryBuildDataSource _qbdsParent)
{
int i;
QueryBuildDataSource qbdsChild;
boolean ret;
;
for (i = 1; i <= _qbdsParent.childDataSourceCount(); i++)
{
qbdsChild = _qbdsParent.childDataSourceNo(i);
if (qbdsChild)
{
if (qbdsChild.joinMode() == JoinMode::InnerJoin &
& qbdsChild.fetchMode() == QueryFetchMode::One2One)//::One2Many)
return true;
if (qbdsChild.childDataSourceCount() > 0 && find1nInnerJoin(qbdsChild))
return true;
}
}
return ret;
}
;
treeNode = iterator.next();
while (treeNode)
{
if (treeNode.sysNodeType() == 202) //Report
{
report = treeNode;
if (report && report.query().dataSourceCount() > 1)
{
qbds = report.query().dataSourceNo(1);
if (find1nInnerJoin(qbds))
info(report.name());
}
}
treeNode = iterator.next();
}
}
{
#AOT
Report report;
TreeNode treeNode = TreeNode::findNode(#ReportsPath);
TreeNodeIterator iterator = treeNode.AOTiterator();
QueryBuildDataSource qbds;
boolean find1nInnerJoin(QueryBuildDataSource _qbdsParent)
{
int i;
QueryBuildDataSource qbdsChild;
boolean ret;
;
for (i = 1; i <= _qbdsParent.childDataSourceCount(); i++)
{
qbdsChild = _qbdsParent.childDataSourceNo(i);
if (qbdsChild)
{
if (qbdsChild.joinMode() == JoinMode::InnerJoin &
& qbdsChild.fetchMode() == QueryFetchMode::One2One)//::One2Many)
return true;
if (qbdsChild.childDataSourceCount() > 0 && find1nInnerJoin(qbdsChild))
return true;
}
}
return ret;
}
;
treeNode = iterator.next();
while (treeNode)
{
if (treeNode.sysNodeType() == 202) //Report
{
report = treeNode;
if (report && report.query().dataSourceCount() > 1)
{
qbds = report.query().dataSourceNo(1);
if (find1nInnerJoin(qbds))
info(report.name());
}
}
treeNode = iterator.next();
}
}
Subscribe to:
Posts (Atom)