You can try below code.
Step 1- A trigger on Contact Object, which will get executed after inserting a Contact Record.
Step 2 - Fetch only those contact where ConvertedFromContact__c is true and pass those contactIds to future method of Handler class.
Step 3 - We are creating a method which is defined as future, as we are working on Setup(User) and Non Setup(Contact) object. Future method will be invoke asynchronously to create a User records for related Contacts.
// Trigger Code
trigger createUserFromLead on Contact (after insert) {
List<User> userList = new List<User>();
Set<Id> contactIds = new Set<Id>();
for(Contact c: Trigger.New){
if(c.ConvertedFromContact__c){
contactIds.add(c.id);
}
}
if(contactIds.size() > 0){
CreateUserHandler.createUserFromContact(contactIds);
}
}
// Handler Code
public with sharing class CreateUserHandler {
@future
public static void createUserFromContact(Set<Id> contactIds)
{
List<User> userList = new List<User>();
List<Profile> profileList = [Select Id from Profile where Name=: 'System Administrator' limit 1];
List<UserRole> roleList = [Select Id from UserRole where Name=: 'CEO' limit 1];
for(Contact contactObj : [Select Id, Name, Email,Username__c from Contact where Id IN: contactIds limit 50000]){
User uObj = new User();
uObj.Username = contactObj.Username__c;
uObj.Email = contactObj.Email;
uObj.Alias = contactObj.Name;
uObj.UserRoleId = roleList[0].Id;
uObj.ProfileId = profileList[0].Id;
uObj.IsActive = true;
uObj.TimeZoneSidKey = 'GMT';
uObj.LanguageLocaleKey = 'en_US';
uObj.EmailEncodingKey = 'UTF-8';
uObj.LocaleSidKey = 'en_US';
uObj.ContactId = contactObj.Id;
userList.add(uObj);
}
try{
insert userList; // insert the user record
}catch(Exception e){
// Catch Exception
}
}
}
References for Future Method in Salesforce