Mark checkbox in all companies AX2012 - axapta

I added a checkbox in PurchParameters table which name is setExchRateVal and I want to mark true this field in my all companies without sql operations.
How can i do this in AX with job?
I tried this but it's not done,
PurchParameters purchParameters ;
while select forUpdate crossCompany purchParameters
{
purchParameters.setExchRateVal = NoYes::Yes;
purchParameters.update();
//info(strFmt("%1 - %2", purchParameters.SetExchRateVal, purchParameters.dataAreaId));
}
AX ERROR :
Update operations are not allowed across companies.

The error is clear. You can't do crossCompany and updates in the same select query. Method 2 below is closer to what you're doing. When updating parameter tables, it can be done a few ways because of the Key on the table.
See below:
PurchParameters purchParametersUpdate;
PurchParameters purchParametersSeek;
DataArea dataArea;
// Method 1
ttsBegin;
while select dataArea
{
changeCompany(dataArea.id)
{
purchParametersUpdate = PurchParameters::find(true);
purchParametersUpdate.setExchRateVal = NoYes::Yes;
purchParametersUpdate.update();
}
}
ttsCommit;
// Method 2
ttsBegin;
while select crossCompany purchParametersSeek
{
purchParametersUpdate = null;
select firstOnly forUpdate purchParametersUpdate
where purchParametersUpdate.RecId == purchParametersSeek.RecId;
if (purchParametersUpdate)
{
//purchParametersUpdate.setExchRateVal = NoYes::Yes;
purchParametersUpdate.update();
}
}
ttsCommit;
info("Done");

Related

Add display method in a listpage form

I want to add a display method in the datasource of a listpage form. I can't add straightly because datasources come from an AOT query. How can I do it?
Thanks for help in advance.
The display method:
public display String255 UserNames()
{
DirPartyName partyName;
DirPersonUser personUser;
DirPerson person;
UserInfo userInfo;
String255 userList = "";
partyName = DirPersonUser::userId2Name(this.UserId);
if(partyName)
{
while select Name from person
exists join personUser
where personUser.PersonParty == person.RecId
&& personUser.User == this.UserId
{
userList += person.Name + ",";
}
}
if (!partyName)
{
while select Name from userInfo
where userInfo.Id == this.UserId
{
userList += userInfo.name + ",";
}
}
partyName = (select firstonly Name from userInfo where userInfo.Id == this.UserId).Name;
if (!partyName)
userList += this.UserId + ",";
strDel(userList,strLen(userList),1);
return userList;
}
I had a same requirement and we did it with a real physical field in the table TrvExpTable after the field is in the table we fill it on opening the list page.
In the init(), before the super(), of the form you can call that method:
public void updateTrvExpTableApprovers()
{
TrvExpTable trvExpTable;
TrvExpTrans trvExpTrans;
WorkflowWorkItemTable workflowItemTable;
String255 approversNames;
HcmWorker HcmWorker;
DirPersonUser dirPersonUser;
Name name;
ttsBegin;
while select forUpdate trvExpTable where trvExpTable.ApprovalStatus == TrvAppStatus::Pending
{
approversNames = "";
while select userId from workflowItemTable
where workflowItemTable.RefRecId == trvExpTable.RecId &&
workflowItemTable.RefTableId == trvExpTable.TableId &&
workflowItemTable.Status == WorkflowWorkItemStatus::Pending
{
select firstonly hcmWorker
join firstonly PersonParty, ValidFrom, ValidTo from dirPersonUser
where dirPersonUser.User == workflowItemTable.userId &&
hcmWorker.Person == dirPersonUser.PersonParty;
name = HcmWorker.name();
if (!name)
{
name = workflowItemTable.userId;
}
if(approversNames)
{
if (!strScan(approversNames, name, 0, 255))
{
approversNames += ', ' + name;
}
}
else
{
approversNames = name;
}
}
trvExpTable.ApproversNames = approversNames;
trvExpTable.update();
}
update_recordSet trvExpTable
setting ApproversNames = ""
where trvExpTable.ApprovalStatus != TrvAppStatus::Pending && trvExpTable.ApproversNames != "";
ttsCommit;
}
It is not the most efficient way but in our case it is working perfect for more than a year now.
Also that way the user could CTRL+G on that field in the grid, which is not a option using the display methods.
Best Regards,
Kristian
Why don't you try writing display method in table method as use same in list page? That is good option.
If you still want to write display method in form data-source level then change your display method like below.
public display String255 UserNames(DataSourcetablename _tableName)
{ ....
Use _tableName where ever you are using "this".
You can refer PurchEditLines form in standard Ax 2012 and see
display ImageRes backOrder(PurchParmLine _purchParmLine).
For more details on display method click here

Bring Vendor Name as a column in LedgerTransAccount form

I am trying to bring the vendor name on each line in the TransAccountForm.
I have written a small piece of code which gets the vendor name when LedgerDimension from LedgerJournalTrans is available:
static void GetVendorName(Args _args)
{
CustAccount custAccount;
VendTable vendTable;
LedgerJournalTrans ledgerJournalTrans;
while select ledgerJournalTrans
{
if (ledgerJournalTrans.AccountType == LedgerJournalACType::Vend)
{
custAccount = DimensionStorage::ledgerDimension2AccountNum(LedgerJournalTrans.LedgerDimension);
select firstOnly vendTable
where vendTable.AccountNum == custAccount;
info(strFmt("Vendor Name: %1, Voucher: %2", DirPartyTable::getName(vendTable.Party), ledgerJournalTrans.Voucher));
}
}
}
But how can I get to run this code in order to bring that new column with the vendor name?
Thanks to Jan B. Kjeldsen I got to this solution:
One of the data source in LedgerTransAccount is GeneralJournalEntry on wich i add the display method.
With the help of SubLedgerVoucher i am able to get one line from LedgerJournalTrans.
public display Name VendorName()
{
Name ret;
LedgerJournalTrans ledgerJournalTrans;
select firstFast firstOnly ledgerJournalTrans
where ledgerJournalTrans.Voucher == this.SubledgerVoucher &&
ledgerJournalTrans.TransDate == this.AccountingDate;
ret = ledgerJournalTrans.AccountType == LedgerJournalACType::Vend ?
vendTable::find(DimensionStorage::ledgerDimension2AccountNum
(ledgerJournalTrans.LedgerDimension)).name() : '';
return ret;
}
After this, I just drag and drop this method on my form's grid.
You can add a display method to the ledgerJournalTrans table:
[SysClientCacheDataMethodAttribute(true)]
display VendName vendName()
{
return this.AccountType == LedgerJournalACType::Vend ? vendTable::find(DimensionStorage::ledgerDimension2AccountNum(this.LedgerDimension)).name() : '';
}
A one-liner.

How to get a list of Companies User Access in Ax 2012?

In Ax 2009, to get a list of companies by user I get it of this way:
static container getAllCompanies()
{
Container companies;
DataArea dataArea;
CompanyDomainList companyDomainList;
AccessRightsList accessRightsList;
UserGroupList userGroupList;
//select all the companies in which current user’s access level is higer than NoAccess
while select id,name from DataArea
Exists join companyDomainList
where companyDomainList.companyId == dataArea.Id
join accessRightsList
where accessRightsList.domainId == companyDomainList.domainId && accessRightsList.accessType > AccessType::NoAccess
join userGroupList
where userGroupList.groupId == accessRightsList.groupId && userGroupList.userId == curuserid()
{
companies += [dataArea.name,dataArea.Id];
}
return companies;
}
but in Ax 2012, I don't have the CompanyDomainList table, how can I get a list of companies that user has access?
User and copmany information is saved in the OMUserRoleOrganization table.
UserId userId = curUserId();
CompanyInfo companyInfo;
OMUserRoleOrganization oMUserRoleOrganization;
container result;
while select companyInfo
exists join oMUserRoleOrganization
where oMUserRoleOrganization.OMInternalOrganization == companyInfo.RecId
&& oMUserRoleOrganization.User == userId
{
result += [companyInfo.Name, companyInfo.DataArea];
}
if (!result)
{
// no specific company for user --> all
while select companyInfo
{
result += [companyInfo.Name, companyInfo.DataArea];
}
}

Ax 2012 tts error

HI i am facing an error while updating a record in the invent table. I am using the following sample code.
static void Job4(Args _args)
{
CsInvBOMSplitQtyCalcHelper bomCalc;
Qty qty;
InventTable inventTable;
InventTable updateInventTable;
BOM bom;
boolean result;
BOMId bomId;
BOMVersion bomVersion;
ItemId item = "1000M-3C-Pcs";
select firstOnly * from bomversion
where bomversion.Active == true
&& bomversion.ItemId == item
&& csIsLengthItem(item) == false;
if (0 != bomVersion.RecId)
{
select * from bom
where bom.BOMId == bomversion.BOMId
exists join inventTable
where bom.ItemId == inventTable.ItemId
&& inventTable.CsIsLengthItem == true;
}
if (0 != bom.RecId)
{
result = true;
bomCalc = CsInvBOMSplitQtyCalcHelper::construct(item);
qty = bomCalc.getAdvicedBOMSpoolQty();
}
ttsBegin;
while select forUpdate updateInventTable
where updateInventTable.ItemId == item
{
updateInventTable.CsInvBOMSplitQty = qty;
updateInventTable.update();
}
ttsCommit;
info(strFmt('%1, %2, %3', result, qty, inventTable.CsInvBOMSplitQty));
}
This is the error I get:
Please help me in resolving this issue.
The error is obviously not caused by this job (but maybe an earlier version).
Just run this small job to reset the TTS level:
static ttsAbort(Args args)
{
ttsabort;
}
TTS level errors are usually caused by programming errors, say calling return before ttsCommit.

how to read each value of a column in a table

Using x++ how to create a job to read each value of a column in a table in Microsoft dynamics AX 2009?
This code will display all the column values for a record.
static void Job1(Args _args)
{
DictTable dictTable = new DictTable(tableNum(CustTable));
DictField dictField;
int counter, fieldId;
CustTable custTable;
anytype value;
select firstonly custTable;
for (counter = 1; counter <= dictTable.fieldCnt(); counter++)
{
fieldId = dictTable.fieldCnt2Id(counter);
dictField = new DictField(tableNum(CustTable), fieldId);
if (!dictField.isSystem())
{
value = custTable.(fieldId);
if(value)
{
info(strFmt('%1 = %2',
dictField.label(),
any2str(value)));
}
}
}
}
For getting all the values for a specific column, please use Carlos Heuberger's code.
One possibility: in the AOT (Ctrl-D) right-click on Jobs and select New Job. In the new window enter something like (using the correct table and column name you want to read):
static void Job()
{
YourTable yourTable;
;
while select TheColumn from yourTable
{
// process yourTable.TheColumn
info(strFmt("value: %1", yourTable.TheColumn));
}
}
but thera are some other ways: Select Statements
Just a slight mod, took out any2str to make my table work:
strFmt('%1 = %2 \r\n', dictField.label(), value);

Resources