This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unable to create PWO requests by VB script for user account-group direct assignments

For Cloud Systems Integration, the sync brings in the CSMUSER and CSMGroup  and creates direct assignments in CSMUserinGroup table.

For these direct assignments, requests are to be created in PWO table , so we have created a process on CSMUserinGroup which creates PWO records.

The script in the process is creating PWO work orders for Self Service Approval workflow products, but failing for the customized approval workflow products.

Error: Error when trying to create request (PersonWantsOrg): One or more errors occurred.:PersonWantsOrg: Write permission denied for value "OrderState"

Script Code: 

Public Function CCC_CreateRequestForAssignment(ByVal XObjectKey As String) As Integer

'Variable declaration
Dim src As IEntitySource = Session.Source
Dim f As ISqlFormatter = Session.SqlFormatter
Dim folderPath As String = Session.Config.GetConfigParm("Custom\TargetSystem\Migration\logFolderPath")
Dim fileName As String = Session.Config.GetConfigParm("Custom\TargetSystem\Migration\logFileName")
Dim logFileName As String = String.Format("{0}\{1}_{2}.log",folderPath, fileName, DateTime.Now.ToString("yyyyMMdd_HHmmss"))
Dim baseObj As IEntity = Nothing
Dim singleUser As IEntity = Nothing
Dim pwoObj As IEntity = Nothing
'Dim pwoObj As ISingleDbObject
Dim userInGroupCol As IEntityCollection
Dim users As IEntityCollection
Dim usersUIDs As New HashSet(Of String)
Dim uidPersonByCSMUserUID As New Dictionary(Of String, String)
Dim orgBRsByCSMGroupCol As IEntityCollection
Dim orgBRsByCSMGroup As New Dictionary(Of String, String)

Dim uidCSMUser As String = String.Empty
Dim uidCSMRoot As String = String.Empty
Dim uidPerson As String = String.Empty
Dim uidBR As String = String.Empty
Dim uidQA As String = String.Empty
Dim uidAccProduct As String = String.Empty
Dim uidOrg As String = String.Empty
'Below line to add the display property for the request
Dim displayOrg As String = String.Empty
'Remove above line if any issues
Dim isSingleObject As Boolean = False
Dim reqCounter As Integer = 0
Dim debugMode As Boolean = False
If Session.Config.GetConfigParm("Custom\TargetSystem\Migration\DebugMode") = "1" Then
debugMode = True
End If

'Validate input value
If String.IsNullOrEmpty(XObjectKey) Then
Throw New Exception("XObjectKey must not be empty!")
End If

'Create logger
Dim logger As New VI.Base.Logging.Logger()
logger.AddWriter(New VI.Base.Logging.FileLogWriter(logFileName))

logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, "Start migration...")
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, "DebugMode: "+debugMode.ToString)

'Check whether the script should be executed for a single assignment or the whole target system and validate key
If XObjectKey.Contains("CSMRoot") Then
'Retrieve CSMRoot object
If Not Session.Source.Exists(Query.From("CSMRoot").SelectAll.Where(f.Comparison("XObjectKey", XObjectKey, ValType.String))) Then
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Serious, String.Format("CSMRoot object could not be found using XObjectkey '{0}'", XObjectKey))
Throw New Exception(String.Format("CSMRoot object could not be found using XObjectkey '{0}'", XObjectKey))
End If
uidCSMRoot = XObjectKey.Substring(22,36)
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, "Execute migration for all direct assignment of application...")
ElseIf XObjectKey.Contains("CSMUserInGroup")
'Retrieve CSMUserInGroup object
If Not Session.Source.Exists(Query.From("CSMUserInGroup").SelectAll.Where(f.Comparison("XObjectKey", XObjectKey, ValType.String))) Then
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Serious, String.Format("CSMUserInGroup object could not be found using XObjectkey '{0}'", XObjectKey))
Throw New Exception(String.Format("CSMUserInGroup object could not be found using XObjectkey '{0}'", XObjectKey))
Else
'Set flag that only a single object should be processed
isSingleObject = True
uidCSMUser = XObjectKey.Substring(72,36)
uidCSMRoot = src.GetSingleValue(Of String)(Query.From("CSMUser").Select("UID_CSMRoot").Where(f.UidComparison("UID_CSMUser", uidCSMUser)))
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, "Execute migration for single assignment...")
End If
Else
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Serious, "Only XObjectKeys of CSMRoot and CSMUserinGroup objects are allowed!")
Throw New Exception("Only XObjectKeys of CSMRoot and CSMUserinGroup objects are allowed!")
End If

'Load collection of applicable CSMUserInGroup entries
If isSingleObject Then
userInGroupCol = src.GetCollection(Query.From("CSMUserInGroup").SelectAll.Where(f.AndRelation(f.Comparison("XObjectKey", XObjectKey, ValType.String), _
f.Comparison("XOrigin", 1, ValType.Int), _
f.Comparison("XMarkedForDeletion", 0, ValType.Int))))
If userInGroupCol.Count = 0 Then
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Serious, "Provided assignment does not match the criteria: XOrigin = 1, XMarkedForDeletion = 0")
Throw New Exception("Provided assignment does not match the criteria: XOrigin = 1, XMarkedForDeletion = 0")
End If

'Load user data for later processing
users = src.GetCollection(Query.From("CSMUser").Select(New String(){"UID_CSMUser", "UID_Person"}).Where(f.AndRelation(f.UidComparison("UID_CSMUser", uidCSMUser), _
f.Comparison("XMarkedForDeletion", 0, ValType.Int, CompareOperator.Equal), _
"Not " & f.EmptyClause("UID_Person",ValType.String))))
Else


userInGroupCol = src.GetCollection(Query.From("CSMUserInGroup").SelectAll.Where(f.AndRelation(String.Format("UID_CSMUser in (Select UID_CSMUser from CSMUser where {0})",f.UIDComparison("UID_CSMRoot", uidCSMRoot)), _
f.Comparison("XOrigin", 1, ValType.Int, CompareOperator.Equal), _
f.Comparison("XMarkedForDeletion", 0, ValType.Int))))

'Load user data for later processing
users = src.GetCollection(Query.From("CSMUser").Select(New String(){"UID_CSMUser", "UID_Person"}).Where(f.AndRelation(f.UidComparison("UID_CSMRoot", uidCSMRoot), _
f.Comparison("XMarkedForDeletion", 0, ValType.Int, CompareOperator.Equal), _
"Not " & f.EmptyClause("UID_Person",ValType.String))))
End If

'Create hashset entries for applicable user ids
For Each user As IEntity In users
If Not usersUIDs.Contains(user.GetValue("UID_CSMUser").String) Then
usersUIDs.Add(user.GetValue("UID_CSMUser").String)
End If
If Not uidPersonByCSMUserUID.ContainsKey(user.GetValue("UID_CSMUser").String) Then
uidPersonByCSMUserUID.Add(user.GetValue("UID_CSMUser").String, user.GetValue("UID_Person").String)
End If
Next

'Create dictionary for applicable BR entries
orgBRsByCSMGroupCol = src.GetCollection(Query.From("OrgHasCSMGroup").SelectAll.Where( _
String.Format("UID_CSMGroup in (Select UID_CSMGroup from CSMGroup where {0})", _
f.UidComparison("UID_CSMRoot", uidCSMRoot))))
For Each brGrpElem As IEntity In orgBRsByCSMGroupCol
If Not orgBRsByCSMGroup.ContainsKey(brGrpElem.GetValue("UID_CSMGroup").String) Then
orgBRsByCSMGroup.Add(brGrpElem.GetValue("UID_CSMGroup").String, brGrpElem.GetValue("UID_Org").String)
End If
Next

'Iterate over assignment entries and create requests
For Each elem As IEntity In userInGroupCol
'Reinitialize variables
uidPerson = String.Empty
uidBR = String.Empty
uidQA = String.Empty
uidAccProduct = String.Empty
uidOrg = String.Empty

'Check whether UID_CSMUser in users collection
If usersUIDs.Contains(elem.GetValue("UID_CSMUser").String) Then
'Check whether BR for UID_CSMGroup exists
If Not orgBRsByCSMGroup.ContainsKey(elem.GetValue("UID_CSMGroup").String) Then
'Continue in case no applicable BR exists
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Warning, String.Format("No BR(Org) object found for CSMGroup '{0}'! Therefore no request could be created for entry (CSMUserInGroup) '{1}'!", elem.GetValue("UID_CSMGroup").String, elem.GetValue("XObjectKey").String))
Continue For
Else
uidBR = orgBRsByCSMGroup.Item(elem.GetValue("UID_CSMGroup").String)
End If

'Fetch QERAssign from BR
If src.TryGetSingleValue(Query.From("QERAssign").Select("UID_QERAssign").Where( _
f.Comparison("ObjectKeyAssignTarget", String.Format("<Key><T>Org</T><P>{0}</P></Key>", uidBR), ValType.String, CompareOperator.Equal)), uidQA) Then
Else
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Warning, String.Format("No QERAssign object found for BR(Org) UID '{0}'! Therefore no request could be created for entry (CSMUserInGroup) '{1}'!", uidBR, elem.GetValue("XObjectKey").String))
Continue For
End If

'Retrieve UID_Person for CSMUser
uidPerson = uidPersonByCSMUserUID.Item(elem.GetValue("UID_CSMUser").String)

'Check whether requests exists
If Not src.Exists(Query.From("PersonWantsOrg").SelectNone.Where(f.AndRelation(f.UidComparison("UID_PersonOrdered", uidPerson), _
f.Comparison("ObjectKeyOrdered", String.Format("<Key><T>QERAssign</T><P>{0}</P></Key>", uidQA), ValType.String, CompareOperator.Equal), _
f.InClause("OrderState", ValType.String, New String(){"Assigned", "OrderProlongate", "OrderUnsubscribe"}) _
))) Then

'Retrieve UID_Org for PWO via AccProduct from QERAssign
uidAccProduct = src.GetSingleValue(Of String)(Query.From("QERAssign").Select("UID_AccProduct").Where(f.UidComparison("UID_QERAssign", uidQA)))
uidOrg = src.GetSingleValue(Of String)(Query.From("ITShopOrg").Select("UID_ITShopOrg").Where(f.UidComparison("UID_AccProduct", uidAccProduct)))
'Below line to add the display property for the request
displayOrg= src.GetSingleValue(Of String)(Query.From("ITShopOrg").Select("Ident_Org").Where(f.UidComparison("UID_AccProduct", uidAccProduct)))
'Remove above line if any issues
Try

' Create order
pwoObj = src.CreateNew("PersonWantsOrg")

Dim dbPropertyBag As PropertyBag = New PropertyBag
dbPropertyBag.PutValue("UID_Org", uidOrg)
'Below line To add the display Property For the request
dbPropertyBag.PutValue("DisplayOrg", displayOrg)
'Remove above line if any issues
dbPropertyBag.PutValue("UID_PersonInserted", uidPerson)
dbPropertyBag.PutValue("UID_PersonOrdered", uidPerson)
dbPropertyBag.PutValue("ObjectKeyOrdered", String.Format("<Key><T>QERAssign</T><P>{0}</P></Key>", uidQA))
dbPropertyBag.PutValue("ObjectKeyAssignment", String.Format("<Key><T>PersonInOrg</T><P>{0}</P><P>{1}</P></Key>",uidBR, uidPerson))
dbPropertyBag.PutValue("OrderReason", "Automatic system request: initial data migration")
dbPropertyBag.PutValue("OrderState", "Assigned")

If Not debugMode Then
pwoObj.CallMethod("FillOrder",dbPropertyBag)

pwoObj.Save(Session)
End If

reqCounter = reqCounter + 1

logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, String.Format("Request created successfully for assignment (CSMUserInGroup): '{0}'", elem.GetValue("XObjectKey").String))
Catch ex As Exception
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Serious, String.Format("Error when trying to create request (PersonWantsOrg): {0}:{1}", ex.Message, ex.InnerException.Message))
End Try
End If

Else
logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Warning, String.Format("CSMUser with UID '{0}' does not have a person assigned. Therefore no request can be created!", elem.GetValue("UID_CSMUser").String))
End If

Next

logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, String.Format("Return value (number of requests created): {0}", reqCounter.ToString))
Return reqCounter

logger.Log("CCC_CreateRequestForAssignment", MsgSeverity.Info, "Finished migration")


End Function