30. One Identity HR

21 февраля 2020 г.

15:29

#IF NOT SCRIPTDEBUGGER

Imports System.Collections.Generic

#END IF

Public Function Z_Aggregate_HR_User_Data_And_Update_Users() As String

logger.trace("ENTER")

'Z_Upload_UNS_Resources_From_CSV_For_System("LabUTK", "C:/Temp/dataimport/LabUTK/Лаборатория УТК - Режимы - new1.csv")

'Z_Upload_Oracle_Assignments_Lab()

'Z_Upload_UNS_Resources_From_CSV_For_System("SUMDP", "C:/Temp/dataimport/SUMDP/СУМ ДП - Режимы - new1.csv")

'Z_Upload_Oracle_Assignments_SUMDP()

'Z_Upload_Oracle_Assignments_Energy()

'Return "ok"

'Z_Upload_Oracle_Assignments_UM()

'Z_Upload_Oracle_Assignments_SUP()

'Z_Upload_Oracle_Assignments_Lab()

'Z_Upload_Oracle_Assignments_SSMPDS()

'Z_Upload_Oracle_Assignments_SUMDP()

'Z_Upload_Oracle_Assignments_MTO()

'Z_Upload_Oracle_Assignments_SSMPHPP()

'Z_Upload_UNS_Resources_From_CSV_For_SSMPHPP_v2()

'Z_Upload_Oracle_Assignments_SPEP()

'Z_Upload_Oracle_Assignments_URA()

'Return "ok"

Try

If False Then

Z_SAP_Sync_Table_ALL_TABLES()

Else

Z_Run_Incremental_AD_Sync()

Z_SAP_Sync_Table_ALL_TABLES()

Connection.Variables.Put("FULLSYNC", True)

Try

Z_Aggregate_And_Update_Departments()

Z_Aggregate_HR_User_Data()

Z_Refresh_Users()

'set "manager" field in persons

Z_Sync_User_Managers()

Finally

Connection.Variables.Remove("FULLSYNC")

End Try

Z_Recon_AD_By_Login()

Z_Connector_Skype_Recon_Incremental()

Z_Connector_Skype_Link_By_GUID()

Z_Provide_MNP_Access()

End If

logger.trace("EXIT")

Catch ex As Exception

Z_Send_Email_To_Error_Auditor("Idm. HR integration error.", "Error in HR integration." & VbCrLf & "Operation will be retried during next task run.", ex)

End Try

Return "ok"

End Function

'true if first employment is 'less' than second; i.e. second one is primary

Public Function Z_Compare_Employments(primaryEmployment As IColElem, nextEmployment As IColElem) As Boolean

If "FIRED" = primaryEmployment.GetValue("CCC_Employee_Status").String And "WORKING" = nextEmployment.GetValue("CCC_Employee_Status").String Then

Return True

End If

If Z_Is_Employment_GPH(primaryEmployment) AndAlso Not Z_Is_Employment_GPH(nextEmployment) Then

Return True

End If

If "WORKING" = primaryEmployment.GetValue("CCC_Employee_Status").String And "FIRED" = nextEmployment.GetValue("CCC_Employee_Status").String Then

Return False

End If

Return primaryEmployment.GetValue("XDateInserted").Date.CompareTo(nextEmployment.GetValue("XDateInserted").Date) > 0

End Function

'Public Function Z_Get_Manager(departmentId As String, currentUserId As String) As String

' Dim f As ISqlFormatter = Connection.SqlFormatter

' If String.IsNullOrEmpty(departmentId) Then

' Return Nothing

' End If

' Dim manId As String = Connection.GetSingleProperty("Department", "UID_PersonHead", f.UidComparison("UID_Department", departmentId)).String

' If Not String.IsNullOrEmpty(manId) And manId \<> currentUserId Then

' Return manId

' End If

' Return Z_Get_Manager(Connection.GetSingleProperty("Department", "UID_ParentDepartment", f.UidComparison("UID_Department", departmentId)).String, currentUserId)

'End Function

Public Function Z_Refresh_User(personId As String) As String

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim employmentsToUpdate As IColDbObject = Connection.CreateCol("CCCEmployment")

Z_Add_All_Columns_To_Output_Result("CCCEmployment", employmentsToUpdate)

employmentsToUpdate.Prototype.WhereClause = f.Comparison("CCC_UID_Person", personId, ValType.String )

employmentsToUpdate.Load()

Dim primaryEmployment As IColElem = Nothing

Dim employmentsToSetDone As New List(Of String)

For Each nextEmployment As IColElem In employmentsToUpdate

If primaryEmployment Is Nothing Then

primaryEmployment = nextEmployment

Else

If Z_Compare_Employments(primaryEmployment, nextEmployment) Then

primaryEmployment = nextEmployment

End If

End If

If nextEmployment.GetValue("CCC_done").Int = 0 Then

employmentsToSetDone.Add(nextEmployment.GetValue("UID_CCCEmployment").String)

End If

Next

Dim person As ISingleDbObject = Connection.CreateSingle("Person", personId)

Dim personIsDisabled As Boolean = person.GetValue("IsInActive").Bool

Dim primaryEmplIsDisabled = "FIRED" = primaryEmployment.GetValue("CCC_Employee_Status").String

Dim dontProcessAttrUpdates As Boolean = False

If personIsDisabled And primaryEmplIsDisabled Then

' don't update attributes if user is still fired

dontProcessAttrUpdates = True

End If

If Not personIsDisabled And primaryEmplIsDisabled Then

' disable user; skip attribute updates

VID_PutValueSafe(person, "ExitDate", DateAdd("d", -1, Now.Date()))

VID_PutValueSafe(person, "IsInActive", 1)

dontProcessAttrUpdates = True

End If

If personIsDisabled And Not primaryEmplIsDisabled Then

' enable user; can't skip attribute updates - should update all attributes

VID_PutValueSafe(person, "ExitDate", DBNull.Value)

VID_PutValueSafe(person, "IsInActive", 0)

End If

If Not dontProcessAttrUpdates Then

If Z_Is_Employment_GPH(primaryEmployment) Then

VID_PutValueSafe(person, "UID_Department", Nothing)

Else

Dim idmDepartmentId As String = Z_Get_Department_By_SAP_Id(primaryEmployment.GetValue("CCC_Department_Id").String)

VID_PutValueSafe(person, "UID_Department", idmDepartmentId)

End If

Z_Copy_General_Attrs_From_Employment_To_Person(person, primaryEmployment)

'VID_PutValueSafe(person, "UID_PersonHead", Z_Get_Manager(idmDepartmentId, personId))

End If

person.Save()

For Each employmentId As String In employmentsToSetDone

Dim employment As ISingleDbObject = Connection.CreateSingle("CCCEmployment", employmentId)

VID_PutValueSafe(employment, "CCC_done", 1)

employment.Save()

Next

Return "ok"

End Function

Private Sub Z_Copy_General_Attrs_From_Employment_To_Person(person As ISingleDbObject, employment As IValueProvider)

VID_PutValueSafe(person, "PersonnelNumber", employment.GetValue("CCC_Employee_Number").String)

VID_PutValueSafe(person, "CCC_RegionName", employment.GetValue("CCC_RegionName").String)

VID_PutValueSafe(person, "Title", employment.GetValue("CCC_PositionName").String)

VID_PutValueSafe(person, "City", employment.GetValue("CCC_CityName").String)

VID_PutValueSafe(person, "CCC_SecClearance_IB", employment.GetValue("CCC_SecClearance_IB").Bool)

VID_PutValueSafe(person, "CCC_SecClearance_KT", employment.GetValue("CCC_SecClearance_KT").Bool)

VID_PutValueSafe(person, "CCC_SecClearance_PDN", employment.GetValue("CCC_SecClearance_PDN").Bool)

VID_PutValueSafe(person, "CCC_CategoryCode", employment.GetValue("CCC_CategoryCode").String)

VID_PutValueSafe(person, "CCC_CategoryName", employment.GetValue("CCC_CategoryName").String)

VID_PutValueSafe(person, "CCC_QualificationName", employment.GetValue("CCC_QualificationName").String)

VID_PutValueSafe(person, "CCC_CompanyCode", employment.GetValue("CCC_CompanyCode").String)

VID_PutValueSafe(person, "CCC_CompanyName", employment.GetValue("CCC_CompanyName").String)

VID_PutValueSafe(person, "CCC_CompanyShortName", employment.GetValue("CCC_CompanyShortName").String)

VID_PutValueSafe(person, "CCC_EmployeeType", If (Z_Is_Employment_GPH(employment), "GPH", "Employee"))

VID_PutValueSafe(person, "Street", employment.GetValue("CCC_Street").String)

End Sub

Private Function Z_Is_Employment_GPH(employment As IValueProvider) As Boolean

Return "ГПХ" = employment.GetValue("CCC_CategoryName").String

End Function

Public Function Z_Refresh_Users() As String

logger.Trace("ENTER")

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim employmentsToUpdate As IColDbObject = Connection.CreateCol("CCCEmployment")

employmentsToUpdate.Prototype("CCC_UID_Person").IsDisplayItem = True

employmentsToUpdate.Prototype.WhereClause = "ccc_done = 0"

employmentsToUpdate.Load()

Dim userIds As New List(Of String)

For Each nextEmployment As IColElem In employmentsToUpdate

Dim personId As String = nextEmployment.GetValue("CCC_UID_Person").String

If Not userIds.Contains(personId) Then

userIds.Add(personId)

Z_Refresh_User(personId)

End If

Next

logger.Trace("EXIT")

Return "ok"

End Function

Public Function Z_Get_Department_By_SAP_Id(department_id As String) As String

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim idmDepartmentId As String = Connection.GetSingleProperty("Department", "UID_Department", f.Comparison("ObjectId", "O " & department_id, ValType.String)).String

Return idmDepartmentId

End Function

Public Function Z_Aggregate_And_Update_Departments() As String

logger.Trace("ENTER")

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim cycleNum As Integer = 0

While cycleNum \< 10

Dim pendingOperations As IColDbObject = Connection.CreateCol("CCCSAPOrgsToUpdate")

Z_Add_All_Columns_To_Output_Result("CCCSAPOrgsToUpdate", pendingOperations)

pendingOperations.Load()

logger.Trace("Iter#" & cycleNum.ToString & ": departments with pending updates: " & pendingOperations.Count.ToString())

If pendingOperations.Count = 0

Exit While

End If

Dim hierChangeFound = False

For Each nextOperation As IColElem In pendingOperations

Dim l_hierChangeFound = False

Dim depId As String = nextOperation.GetValue("UID_Department").String

Dim parDepId As String = nextOperation.GetValue("UID_ParentDepartment").String

Dim shortname As String = nextOperation.GetValue("shortname").String

Dim fullname As String = nextOperation.GetValue("fullname").String

logger.Trace("processing " & nextOperation.GetValue("change_type").String & " for " & fullname & " (" & nextOperation.GetValue("department_sap_id").String & ")")

Try

Dim departmentObj As ISingleDbObject = Nothing

If String.IsNullOrEmpty(depId) Then

departmentObj = Connection.CreateSingle("Department")

VID_PutValueSafe(departmentObj, "ObjectID", "O " + nextOperation.GetValue("department_sap_id").String)

VID_PutValueSafe(departmentObj, "ImportSource", "SAP")

l_hierChangeFound = True

Else

departmentObj = Connection.CreateSingle("Department", depId)

End If

VID_PutValueSafe(departmentObj, "DepartmentName", VID_Left(fullname, 128))

VID_PutValueSafe(departmentObj, "Description", fullname)

VID_PutValueSafe(departmentObj, "CustomProperty01", nextOperation.GetValue("abbrev").String)

VID_PutValueSafe(departmentObj, "ShortName", VID_Left(shortname, 64))

If Not String.IsNullOrEmpty(parDepId) Then

If parDepId \<> departmentObj.GetValue("UID_ParentDepartment").String Then

logger.trace("set UID_ParentDepartment = " & parDepId & " for " & nextOperation.GetValue("department_sap_id").String)

VID_PutValueSafe(departmentObj, "UID_ParentDepartment", parDepId)

l_hierChangeFound = True

End If

End If

departmentObj.Save()

Catch ex As Exception

logger.Error(ex, "error while processing department change for " & fullname & " (" & nextOperation.GetValue("department_sap_id").String & ")")

l_hierChangeFound = False

End Try

If l_hierChangeFound Then

hierChangeFound = l_hierChangeFound

End If

Next

If Not hierChangeFound Then

Exit While

End If

cycleNum = cycleNum + 1

End While

Logger.Trace("EXIT")

Return "ok"

End Function

Public Function Z_Aggregate_HR_User_Data() As String

logger.Trace("ENTER")

Connection.Variables.Put("DONTGENERATEONPERSONINSERTPROCESS", True)

Try

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim pendingOperations As IColDbObject = Connection.CreateCol("CCCHRUserChangesToHandle")

Z_Add_All_Columns_To_Output_Result("CCCHRUserChangesToHandle", pendingOperations)

pendingOperations.Load()

logger.Trace("users with pending updates: " & pendingOperations.Count.ToString())

For Each nextOperation As IColElem In pendingOperations

logger.Trace("processing " & nextOperation.GetValue("operation_type").String & " for " & nextOperation.GetValue("employee_number").String)

Connection.BeginTransaction()

Try

Dim operType As String = nextOperation.GetValue("operation_type").String

Dim operDetails As String = nextOperation.GetValue("operation_details").String

If "HIRE" = operType And String.IsNullOrWhiteSpace(operDetails) Then

logger.trace("empty oper details for HIRE operation")

Continue For

End If

Dim employmentId = nextOperation.GetValue("UID_CCCEmployment").String

'Dim title_id = nextOperation.GetValue("title_id").String

Dim department_id = nextOperation.GetValue("department_id").String

Dim position_id = nextOperation.GetValue("position_id").String

Dim first_name = nextOperation.GetValue("first_name").String

Dim last_name = nextOperation.GetValue("last_name").String

Dim middle_name = nextOperation.GetValue("middle_name").String

Dim birthDate As Date = nextOperation.GetValue("birth_date").Date

Dim person As ISingleDbObject = Nothing

Dim obj As ISingleDbObject = Nothing

'init objects from DB

If Not String.IsNullOrEmpty(employmentId) Then

obj = Connection.CreateSingle("CCCEmployment", employmentId)

person = Connection.CreateSingle("Person", obj.GetValue("CCC_UID_Person").String)

logger.Trace("target person = " & person.GetValue("CentralAccount").String)

End If

'check if user has "IgnoreHREvents" flag

If person IsNot Nothing Then

Dim ignEv As Boolean = Z_Check_If_Ignore_Events(person)

logger.Trace("CCC_IgnoreHREvents = " & ignEv)

If ignEv Then

logger.Trace("ignoring event")

Continue For

End If

End If

If "FIRE" = operType Then

VID_PutValueSafe(obj, "CCC_Employee_Status", "FIRED")

'VID_PutValueSafe(obj, "CCC_End_Date", DateAdd("d", -1, nextOperation.GetValue("action_begda").Date))

VID_PutValueSafe(obj, "CCC_done", 0)

obj.Save()

Continue For

End If

If "HIRE" = operType Then

obj = Connection.CreateSingle("CCCEmployment")

End If

VID_PutValueSafe(obj, "CCC_CategoryCode", nextOperation.GetValue("category_code").String)

VID_PutValueSafe(obj, "CCC_CategoryName", nextOperation.GetValue("category_name").String)

Dim idmDepartmentId As String = Nothing

If Not Z_Is_Employment_GPH(obj) Then

If String.IsNullOrEmpty(department_id) Then

logger.Trace("department_id is empty; skipping this record")

Continue For

End If

idmDepartmentId = Z_Get_Department_By_SAP_Id(department_id)

If String.IsNullOrEmpty(idmDepartmentId) Then

logger.Trace("cannot find idm department for " & department_id & "; skipping this record")

Continue For

End If

End If

If String.IsNullOrEmpty(last_name) Then

logger.Trace("last_name is empty; skipping this record")

Continue For

End If

If String.IsNullOrEmpty(first_name) Then

logger.Trace("first_name is empty; skipping this record")

Continue For

End If

Dim isUserCreation As Boolean = False

VID_PutValueSafe(obj, "CCC_RegionName", nextOperation.GetValue("region_name").String)

VID_PutValueSafe(obj, "CCC_CityName", nextOperation.GetValue("city_name").String)

VID_PutValueSafe(obj, "CCC_SecClearance_IB", nextOperation.GetValue("secclearance_ib").Bool)

VID_PutValueSafe(obj, "CCC_SecClearance_KT", nextOperation.GetValue("secclearance_kt").Bool)

VID_PutValueSafe(obj, "CCC_SecClearance_PDN", nextOperation.GetValue("secclearance_pdn").Bool)

VID_PutValueSafe(obj, "CCC_QualificationName", nextOperation.GetValue("qualification_name").String)

VID_PutValueSafe(obj, "CCC_CompanyCode", nextOperation.GetValue("company_code").String)

'logger.Trace("company_name = " & nextOperation.GetValue("company_name").String)

VID_PutValueSafe(obj, "CCC_CompanyName", nextOperation.GetValue("company_name").String)

'logger.Trace("company_name 2 = " & obj.GetValue("CCC_CompanyName").String)

VID_PutValueSafe(obj, "CCC_CompanyShortName", nextOperation.GetValue("company_short_name").String)

'logger.Trace("street = " & nextOperation.GetValue("street").String)

VID_PutValueSafe(obj, "CCC_Street", nextOperation.GetValue("street").String)

'logger.Trace("street 2= " & obj.GetValue("CCC_Street").String)

If Not Z_Is_Employment_GPH(obj) Then

VID_PutValueSafe(obj, "CCC_PositionName", nextOperation.GetValue("position_name").String)

VID_PutValueSafe(obj, "CCC_Department_Id", department_id)

VID_PutValueSafe(obj, "CCC_Position_id", position_id)

'VID_PutValueSafe(obj, "CCC_Title_Id", title_id)

Else

VID_PutValueSafe(obj, "CCC_Department_Id", Nothing)

VID_PutValueSafe(obj, "CCC_Position_id", Nothing)

VID_PutValueSafe(obj, "CCC_Title_Id", Nothing)

'VID_PutValueSafe(obj, "CCC_PositionName", Nothing)

End If

VID_PutValueSafe(obj, "CCC_SNILS", nextOperation.GetValue("snils").String)

If "HIRE" = operType Then

VID_PutValueSafe(obj, "CCC_Source_Id", nextOperation.GetValue("hr_source_id").String)

VID_PutValueSafe(obj, "CCC_Employee_Number", nextOperation.GetValue("employee_number").String)

Dim personId As String = Nothing

If operDetails.Contains("Person") Then

personId = Connection.CreateSingle(New DbObjectKey(operDetails)).getValue("UID_Person").string

ElseIf False 'not automatic search

'condition to search matching user by last name, first name, midle name, birth date

Dim personWhereByFioAndDB As String = f.Comparison("LastName", last_name, ValType.String ) & " and " & f.Comparison("FirstName", first_name, ValType.String )

If Not String.IsNullOrEmpty(middle_name) Then

personWhereByFioAndDB = personWhereByFioAndDB & " and " & f.Comparison("MiddleName", middle_name, ValType.String )

Else

personWhereByFioAndDB = personWhereByFioAndDB & " and MiddleName is null"

End If

personWhereByFioAndDB = personWhereByFioAndDB & " and " & f.Comparison("BirthDate", birthDate, ValType.Date )

'condition to search maching user by snils

Dim personWhereBySnils As String = Nothing

If Not String.IsNullOrEmpty(nextOperation.GetValue("snils").String) Then

Dim partNameMatchSqls As New List(Of String)

partNameMatchSqls.Add("(" & f.Comparison("p.LastName", last_name , ValType.String) & " and " & f.Comparison("p.FirstName", first_name , ValType.String) & ")")

partNameMatchSqls.Add("(" & f.Comparison("p.LastName", last_name , ValType.String) & " and " & f.Comparison("p.MiddleName", middle_name , ValType.String) & ")")

partNameMatchSqls.Add("(" & f.Comparison("p.MiddleName", middle_name , ValType.String) & " and " & f.Comparison("p.FirstName", first_name , ValType.String) & ")")

personWhereBySnils = "UID_Person in (select p.uid_person from person p inner join CCCEmployment e on e.CCC_UID_Person=p.uid_person and " & f.Comparison("e.CCC_SNILS", nextOperation.GetValue("snils").String, ValType.String) & " and (" & String.Join(" or ", partNameMatchSqls) & "))"

End If

For Each nextSql As String In {personWhereBySnils, personWhereByFioAndDB}

If String.IsNullOrEmpty(nextSql) Then

Continue For

End If

personId = Connection.GetSingleProperty("Person", "UID_Person", nextSql)

logger.Trace("Searching user with condition " & nextSql)

logger.Trace("result = " & personId)

If Not String.IsNullOrEmpty(personId) Then

Exit For

End If

Next

End If

If Not String.IsNullOrEmpty(personId) Then

logger.Trace("HIRE operation for already existing user " & personId)

person = Connection.CreateSingle("Person", personId)

If Z_Check_If_Ignore_Events(person) Then

logger.Trace("user has CCC_IgnoreHREvents flag")

Continue For

End If

Else

person = Connection.CreateSingle("Person")

isUserCreation = True

VID_PutValueSafe(person, "UID_Department", idmDepartmentId)

VID_PutValueSafe(person, "ImportSource", "SAP")

logger.Trace("after setting ImportSource = " & person.GetValue("ImportSource").String)

'VID_PutValueSafe(person, "UID_PersonHead", Z_Get_Manager(idmDepartmentId, Nothing))

'VID_PutValueSafe(person, "UID_PersonHead", Z_Get_User_Manager_By_Employee_number(nextOperation.GetValue("employee_number").String))

Z_Copy_General_Attrs_From_Employment_To_Person(person, obj)

End If

Else

'do nothing - already initiated in code above

End If

If isUserCreation OrElse person.GetValue("PersonnelNumber").String = nextOperation.GetValue("employee_number").String Then

VID_PutValueSafe(person, "LastName", last_name)

VID_PutValueSafe(person, "MiddleName", middle_name)

VID_PutValueSafe(person, "FirstName", first_name)

VID_PutValueSafe(person, "BirthDate", birthDate)

End If

'If isUserCreation AndAlso Not String.IsNullOrEmpty(nextOperation.GetValue("operation_details").String)

If isUserCreation AndAlso operDetails.Contains("ADSAccount")

Dim adacc As ISingleDbObject = Connection.CreateSingle(New DbObjectKey(operDetails))

VID_PutValueSafe(person, "CentralAccount", adacc.GetValue("SAMAccountName").String)

VID_PutValueSafe(person, "CentralSAPAccount", adacc.GetValue("ExtensionAttribute14").String)

End If

person.Save()

If isUserCreation Then

' Z_Sync_User_Managers(person.GetValue("UID_Person").String)

End If

If "HIRE" = operType Then

VID_PutValueSafe(obj, "CCC_UID_Person", person.GetValue("UID_Person").String)

End If

VID_PutValueSafe(obj, "CCC_End_Date", DBNull.Value)

VID_PutValueSafe(obj, "CCC_Employee_Status", "WORKING")

'VID_PutValueSafe(obj, "CCC_done", If(isUserCreation, 1, 0))

VID_PutValueSafe(obj, "CCC_done", 0)

obj.Save()

Connection.CommitTransaction

Catch ex As Exception

logger.error(ex, "error in hr aggregation")

Connection.RollbackTransaction

Finally

If Connection.TransactionOpen

Connection.CommitTransaction

End If

End Try

Next

'pendingOperations = Connection.CreateCol("CCCEmployment")

'pendingOperations.Load()

'Return "" & pendingOperations.Count

Finally

Connection.Variables.Remove("DONTGENERATEONPERSONINSERTPROCESS")

End Try

logger.Trace("EXIT")

Return "ok"

End Function

Private Function Z_Check_If_Ignore_Events(person As ISingleDbObject) As Boolean

If person.GetValue("CCC_IgnoreHREvents").Bool Then

Dim ignoreUntil As Date = person.GetValue("CCC_IgnoreHREventsUntil").Date

If ignoreUntil = Nothing

Return True

Else

' if "ignore until" is in future then ignore event

Return Date.Today().CompareTo(ignoreUntil) \<= 0

End If

Else

Return False

End If

End Function

Public Function Z_Sync_Department_Managers() As String

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim pendingOperations As IColDbObject = Connection.CreateCol("CCCOrgsToChangeManager")

pendingOperations.Prototype("NewManager").IsDisplayItem = True

pendingOperations.Prototype("UID_Department").IsDisplayItem = True

pendingOperations.Load()

For Each nextOperation As IColElem In pendingOperations

Dim obj As ISingleDbObject = Connection.CreateSingle("Department", nextOperation.GetValue("UID_Department").String)

VID_PutValueSafe(obj, "UID_PersonHead", nextOperation.GetValue("NewManager").String)

obj.Save()

Next

Return "ok"

End Function

Public Function Z_Sync_User_Managers(Optional persId As String = Nothing) As String

Dim f As ISqlFormatter = Connection.SqlFormatter

Dim pendingOperations As IColDbObject = Connection.CreateCol("CCCUsersToChangeManagers")

pendingOperations.Prototype("newmanager").IsDisplayItem = True

pendingOperations.Prototype("currentmanager").IsDisplayItem = True

pendingOperations.Prototype("uid_person").IsDisplayItem = True

If Not String.IsNullOrEmpty(persId) Then

pendingOperations.Prototype.WhereClause = f.UidComparison("uid_person", persId)

End If

pendingOperations.Load()

For Each nextOperation As IColElem In pendingOperations

Dim obj As ISingleDbObject = Connection.CreateSingle("Person", nextOperation.GetValue("uid_person").String)

VID_PutValueSafe(obj, "UID_PersonHead", nextOperation.GetValue("newmanager").String)

obj.Save()

Next

Return "ok"

End Function