basics of importing accounts/contacts/users

Hello all,
I’m brand new to SuiteCRM. Indeed, I’m new to CRMs in general. I have it running on a Debian server, using MySQL and Nginx in case that matters. I’m on version 7.9.6.

Right now, I’m getting used to things as I work with my boss to evaluate SuiteCRM and see if it’s a good fit for the company. The task I’ve just been given is to take records from our AS400 and import them, then merge them daily, into SuiteCRM. I have a long list of customer accounts which I have to turn into accounts with one or more contacts per account, a list of sales reps I have to turn into users, and relationships between them I have to automatically create. I’ve so far come up with the following questions:

  • How can I create links between records, existing or imported? Assigning users to own accounts or contacts, making a contact be contained in an account, that kind of thing?
  • Once I know what I’m doing, will I be able to automate this whole process? I’d like to query the 400, generate a file or pass some JSON into a program, and update everything once a day or so.

I know more questions will come up, but that’s it for now. The manual explains things pretty well, but it doesn’t mention automation or connecting records to those in other modules. Thanks for any help.

For your data design, this should help:

https://pgorod.github.io/Concepts-Accounts-Contacts/

For learning how to automate, check out Jim Mackin’s eBook “SuiteCRM for Developers”.

There are a few different approaches, using PHP and “beans” to import intelligently, or directly writing into the database with SQL, or preparing things in Excel/Calc and then importing through the UI.

Thanks. Your blog is proving quite informative.

I’m a programmer, more or less, so SQL is fine with me. I just don’t know the table structure enough to make sure I get things right. A single table is easy, since I can just look at the columns, but it’s the relationships I worry about. Is there anywhere that lays out how to tie members of modules together, setting up parents and the like? PHP would be fine, too, if that would be easier than SQL queries.

Speaking of parents, is there any way to define that right in my CSV file for basic or automated importing? Thanks again!

If you can do PHP you’re better off than directly with SQL, because the SuiteCRM “beans” classes will take care of building those relationships for you. That’s all in the eBook.

SQL: if you examine the database with phpmyadmin you can get a sense of how the tables connect. Each record has an id (like 72c555b3-0ead-d66c-4c2a-57549a2e130b), but you can create your own as long as it’s a unique identifier. Look for tables called like accounts_contacts where the relationships are created (linking and id from contacts to an id from accounts).

CSV imports can do some very basic relationships, I think - like if you import a Contact with a field called Account that matches an existing Account in the database, I think SuiteCRM will link it up as a relationship. But I never really tried it.

My advice is: use PHP.

1 Like

PHP, specifically using beans, does indeed seem to be my best bet. One thing I can’t quite work out, even after reading the chapters of the book, is what to include to get my PHP to recognize all the SC classes I’ll need to work with beans. I’m looking through the modules included in 7.9.6, but I’m not finding much to get me started.

Say I have a contact. I’ve manually set up a user with the username of ahall. I want to add a contact to ahall, and to a company called Alex’s Company. My contact should be part of that account as well as the ahall user. Here’s my guess, written mostly in pseudocode:

//include the necessary files
require(??);

//get the user’s account
$userBeanID = 0;
$userBean = BeanFactor::newBean(‘Users’, $userBeanID)
$userBean->get_list(‘ahall’)[0]; //assuming 1 result
if($userBeanID === null) { //this is a new record, so our user must not exist
echo “User does not exist.”;
exit;
}
//add the contact bean?
$contactBean = BeanFactory::newBean(‘Contacts’, $contactBeanID);
//$contactBean is a new bean, hopefully; we’d run the ID check here, making sure it IS null this time
$contactBean->firstName = ‘John’;
//and so on
$contactBean->save();

//we now need to relate the two beans, somehow
$userBean->contacts->//not sure here

Hopefully you can see what I’m going for, and where I’m unsure. Eventually, I’ll be automating this, likely by having a PHP file read a text file created by a query run against our AS400. For now, though, I just want to work out the process for making new beans, modifying the correct existing ones, and establishing relationships between beans. Thanks.

Read the eBook section about EntryPoints, define your file as an entry point.

Then the reference to stuff like this should be enough

 BeanFactory::getBean("Contacts");

Thanks! I have a PHP file that displays the number of users, but that simple thing means all the behind-the-scenes stuff is working as expected.

One question though. Is there a faster way to test changes? Right now, I :qw in VIM, run a quick repair, and have to go from there back to the test page. Can I make it so I need only refresh the test page? Development Mode is probably good for that, but will that have any consequences I should consider before enabling it?

Why do you run a Quick Repair? I don’t think it’s needed.

Depends on what you’re changing, of course, but for this kind access-the-beans stuff no repair is needed. Only when you change files that SuiteCRM needs to “pre-process” in order to generate other files.

So I think you only need to refresh the test page.

Refreshing doesn’t load any changes. I’ve found that, even with developer mode enabled, my changes to testEntryPoint.php aren’t shown until I do a repair. Did I put the file in the wrong place? I followed the book’s instruction and put it in suiteCRM_dir/custom/extension/application/Ext/EntryPointRegistry. It works, and I even see incorrect queries appearing as fatal errors in suitecrm_dir/suitecrm.log as I hoped. But my PHP won’t do anything I tell it to until I run a quick repair, for some reason.

No, really, you should not need a QRR. There must be some cache betraying you in-between.

What is the URL you’re using to access your file?

Have you tried a CTRL-F5 refresh, instead of a simple F5?

Also, try changing the file, and then accessing it from another browser you’ve never used for this. That way you can tell whether it’s alocal cache problem, or a server-side cache problem.

Good ideas. Ctrl-f5 didn’t help. Neither did switching browsers. I modified my php file, and tried your suggestions as well as restarting Nginx and PHP5-FPM. In all cases, I saw the old PHP file. I even tried turning the “sendfile” command off in nginx.conf, but that didn’t seem to make a difference, so I turned it back on. Only a quick repair and rebuild seems to force SC to pick up my modifications, for some reason.

Unrelated to updating files, I’m trying to get related beans to work. I’m just added a user with a bean, which is great. Now I want to do two things: add an email address for that user, and make an account owned by the user. The account should actually be easier, as I can’t figure out which module to use to give users email addresses.

I suppose I have two questions. How do I assign an email address to a user, and how do I make a user own an account? I’m reading the part of the book on relationships, but I’m not quite getting it. How are relationships tied to beans? How do I specify ownership once I have beans for, say, a user and an account loaded? I can obtain/create beans, but I don’t understand how to tie them together. Thanks.

If $person is a Contact Bean, you can simply assign

$person->email1 = "me@there.com"

And then, what do you mean to “own” the Account?

  1. if you mean have the account assigned to someone, then that is a field you set in the bean:

global $current_user;
$cuser = $current_user->id;

$bean->assigned_user_id = $cuser;
  1. If you mean make the Account be part of a security group, then something like this:

                if (is_null($account)) {
		    $account = BeanFactory::newBean("Accounts");
                    $account->parent_id = $parent_account_id; // for nested accounts
                    $account->name = $newname;
                    $account->save();
                    $securityTeam = new SecurityGroup();
                    $securityTeam->retrieve_by_string_fields(array('name' => $secgroupname ));
                    $account->load_relationship('SecurityGroups');
                    $account->SecurityGroups->add($securityTeam->id);
                }

You’ll have to adapt that code. With this bit I think you can learn how to use relationships, since setting the Security Group is setting a relationship. You can do a similar thing to make a Contact belong to an Account. There are many examples online (once you know what to search for). Good luck.

Thanks for the in-depth answer! I’m surprised that email1 will work, since I didn’t see it in the list of fields for users when I was looking around the studio. But I’m glad it’s that easy! :slight_smile:

Yes, I meant your first example, where an account is bound to a user. That way, each salesperson can have their own accounts, with contacts in each account, and not worry about other accounts. I’ll use groups, but I think for contacts, accounts, meetings, notes, and most other things, I’ll just be assigning directly to users if I have to automate entry of any of them.

I also realized I didn’t answer your question about my URL for the non-refreshing PHP file. I go to:

crm.example.com/index.php?entryPoint=testEntryPoint

where testEntryPoint is the name I define in my PHP file. It loads that way, so I know it works, but nothing I do will get updates to the PHP to show on the site except a QRR.

I don’t know about your refresh issue, maybe it’s something specific to Nginx… I always use Apache.

Good luck with your code.