As you known, If you have multi-companies in AX, each company has his local administrator to manage his users and groups.
Usually, local administrator has manage his users and groups rights, he will have rights on other company users and groups too.
But as a regional IT, he should have fully rights on all companies.
The attachment is the customizations in Ax3 sp3(DownLoad).
Defination:
Each companies' users and groups should use two letters for short. Take a example: America, using am001 as a user id, amfar as a user group.
am must be used for all users and groups in this company.
Customizations:
1, Use a table to save regional IT users list. RITUserInfo table.
2, SysUserInfo Form
2.1 In DS->UserInfo table->executeQuery(), only show one local company's users
public void executeQuery()
{
SysASPClientTable aspClientTable = this.aspClient();
//added by jacky for show local unit users start 20081224
Query qr ;
QueryBuildRange range, range2;
QueryBuildDataSource qbdsuserinfo ;
str _userpref ;
RITUserInfo _rituserinfo ;
//added by jacky for show local unit users end 200812124
;
//added by jacky for show local unit users start 20081224
select _rituserinfo where _rituserinfo.Id == curuserid() ;
if(!_rituserinfo.Id)
{
_userpref = substr(curuserid(),1,2) ;
qr = this.query() ;
qbdsuserinfo = qr.dataSourceName("UserInfo") ;
qbdsuserinfo.clearRanges() ;
range2 = qbdsuserinfo.addRange(fieldnum(UserInfo,Id)) ;
range2.value(_userpref+'*') ;
}
else
{
}
//added by jacky for show local unit users end 20081224
if (aspClientTable)
{
range = this.query().dataSourceNo(1).range(1);
range.value(aspClientTable.range());
}
super();
}
2.2 In DS->UserInfo table->write(), It ensures only user id which followed the naming defination.
void write()
{
SysUserInfo _sysUserInfo;
UserInfo _userinfo ;
UserGroupList _usergroupl ;
RITUserInfo _rituserinfo ;
super();
select firstonly recId from _sysUserInfo
where _sysUserInfo.id == userinfo.id;
select _rituserinfo where _rituserinfo.Id == curuserid() ;
if (!_sysUserInfo)
{
//condition added by jacky for user creating control 20081224
if (substr(curuserid(),1,2) == substr(userinfo.id,1,2) || _rituserinfo.RecId)
{
_sysUserInfo.initValue();
_sysUserInfo.id = userinfo.id;
_sysUserInfo.insert();
}
else
{
delete_from _userinfo where _userinfo.id == userinfo.id ;
error("Please not add any groups on this user, this user will be deleted!") ;
error("System can't create the user, Please use the first and second char of your unit as the first and second char of user id! ") ;
}
}
}
2.3 In Form methodes->add a method: userGroupRightData(). Show loca company's groups in group list
container userGroupRightData()
{
Query q = new Query();
QueryBuildDataSource qb,qbc;
queryRun qr;
container data, dataRow;
Common dataTableBuffer;
int i;
int len = conLen(listPanel.parmDataContainerFieldIds());
fieldId fieldId;
RITUserInfo _rituserinfo ;
;
select _rituserinfo where _rituserinfo.Id == curuserid() ;
qb = q.addDataSource(tablenum(UserGroupInfo)) ;
if(!_rituserinfo.Id)
{
qb.addRange(fieldnum(UserGroupInfo,id)).value(substr(curuserid(),1,2)+'*');
}
qr = new QueryRun(q);
while(qr.next())
{
dataTableBuffer = qr.get(listPanel.parmDataTable());
dataRow = dataTableBuffer.(listPanel.parmDataField());
for (i=1; i<=len; i++)
{
fieldId = conpeek(listPanel.parmDataContainerFieldIds(), i);
dataRow += dataTableBuffer.(fieldId);
}
data += [dataRow];
}
return data;
}
2.4 In Form method->Init(), invoking userGroupRightData().
listPanel = sysListPanelRelationTableCallBack::newForm(element, control::Groups, "@SYS25427", "@SYS57280", #ImageUserGroup,
tableNum(UserGroupList),
fieldNum(UserGroupList, groupId),
fieldNum(UserGroupList, userid),
tableNum(UserGroupInfo),
fieldNum(UserGroupInfo, id),
[fieldNum(UserGroupInfo, id), fieldNum(UserGroupInfo, name)],
0, '',
identifierStr(Validate),'', identifierStr(userGroupRightData));
3, SysUsergroupInfo Form. All steps should follow all steps of 2 Item.
4, Class changed
4.1 SysListPanel Class->Add method: It ensures local administrator can't create no-company users/groups
public void add(FormListNext FormListNext = FormListNext::SELECTED)
{
FormListItem formListItem;
int idx = viewRight.getNextItem(FormListNext);
container data;
RITUserInfo _rituserinfo ;
startLengthyOperation();
viewRight.lockWindowUpdate(true);
viewLeft.lockWindowUpdate(true);
select _rituserinfo where _rituserinfo.Id == curuserid() ; //added by jacky xu for users and groups admin 20081224
while(idx != -1)
{
formListItem = viewRight.getItem(idx);
//The condition added by jacky xu for users and groups admin 20081224
if(substr(curuserid(),1,2) != substr(formListItem.toString(),1,2) && !_rituserinfo.Id && Global::hasSecuritykeyAccess(securityKeyNum(HDA_Admin_DevControl),AccessType::View))
{
error("System can't create the user or groups, Please use the first and second char of your unit as the first and second char of the user or group id! ") ;
return ;
}
else
{
//orginal code start
if (this.validate(formListItem.data(), AddRemove::Add))
data += formListItem.data();
idx = viewRight.getNextItem(FormListNext, idx);
//orginal code end
}
}
if (conLen(data))
{
this.addData(data);
idx = viewRight.getNextItem(FormListNext);
while(idx != -1)
{
formListItem = viewRight.getItem(idx);
if (conFind(data, formListItem.data()))
{
this.moveOneItem(viewRight, viewLeft, idx);
idx = viewRight.getNextItem(FormListNext);
}
else
idx = viewRight.getNextItem(FormListNext, idx);
}
this.enableButtons();
}
viewRight.lockWindowUpdate(false);
viewLeft.lockWindowUpdate(false);
this.reload(AddRemove::Add);
}
4.2 SysListPanelRelationTable class->AddData(). It ensures local administrator can't map no-company users/groups
void addData(container data)
{
//The condition added by jacky xu for users and groups admin 20081224
RITUserInfo _rituserinfo ;
;
select _rituserinfo where _rituserinfo.Id == curuserid() ;
if(substr(curuserid(),1,2) != substr(relationRangeValue,1,2) && !_rituserinfo.Id && Global::hasSecuritykeyAccess(securityKeyNum(HDA_Admin_DevControl),AccessType::View))
{
error("You can't operate this user or group: " + relationRangeValue +"! ") ;
return ;
}
else
{
//orginal codes start
SysListPanelRelationTable::server_addData(
data,
relationTable,
relationField,
relationRangeField,
relationRangeValue);
//orginal codes end
}
}
5. We can hide development security keyon SK settings list
In class: SysSecurityViewAll->Build method.
void build(int parentKey = 0, int parentNode = 0)
{
FormTreeItem item;
TmpSecurityTree tmpTable;
int node;
SysDictMenu sysDictMenu;
MenuFunction menuFunction;
RITUserInfo _rituserinfo ;
;
tmpTable.setTmpData(securityTable);
select _rituserinfo where _rituserinfo.Id == curuserid() ;
while select tmpTable
order by name
where tmpTable.parent == parentKey
{
//The condition added by jacky for hiding development rights in SK settings 20081224
if ((substr(tmpTable.name,2,999)=="@sys9605" || subStr(tmpTable.name,2,999)=="@HDA4441") && !(_rituserinfo.RecId))
{
continue ;
}
else
{
//orginal code start
if (tmpTable.type == SysSecurityType::SecurityKey)
tmpTable.name = subStr(tmpTable.name,2,999);
item = this.createFormTreeItem(tmpTable);
node = tree.addItem(parentNode, 0, item);
item = tree.getItem(node);
item.stateImage(1);
item.stateExpandedOnce(false);
item.children(tmpTable.children);
if (tmpTable.isWeb)
item.overlayImage(imageWeb);
tree.setItem(item);
this.build(tmpTable.id, node);
//orginal code end
}
}
}
All is OK now.