Logic Hooks

I am researching the viability of using logic hooks to query the database in a different module and associate a record with a related record in a different module.

Aka

Import is clicked, before or after save? logic hook to check if a number of field criteria is matched to the import file record. If so, the ID is applied to the related record field and the relationship is created. This is to eliminate having to download and match IDs to import files provided on a weekly basis in excel before importing as this is very time intensive.

I will also be trying to modify a status of a person in a dropdown list based on the most recent payment date of the import data. If the person in the record doesnt appear in an import they will be changed to an inactive status.

Is this possible using logic hooks and how? Or am I way off base?

I have read the developer documentation and am still kind of at a loss.

You might be better off just writing an import script.

Technically it’s a custom entry-point (see Dev guide), but really it’s just some PHP that grabs your CSV, parses it into lines, then adds or modifies the SuiteCRM database using the Beans objects. You can add a lot of your logic (checks and validations, conditionals, etc), create relationships, etc.

It can also be a logic hook, but if the action you’re trying to hook is the import, you can simply skip the default importer and do your own, it’s not complicated.

You might find some examples online - from a quick search I found this discussion which has a bit of sample code (not much)
https://suitecrm.com/suitecrm/forum/suitecrm-7-0-discussion/18400-how-to-include-beans-function-in-custom-code

Is there a way to map to a record besides using the record ID. I have plenty of unique data in each record. That would probable eliminate all this extra mess. The issue is that I’m provided with documents from external sources (over 50), and obviously they don’t have our record ID’s, nor will they change the format that they are providing them. If I can key off of a unique field or multiple fields (for more accuracy) then problem solved.

eg.

if ((field = import_field) && (field = import_field) && (field = import field))
retrieve = ID?
create relationship
create related record

maybe check other fields if any of the above are null.

The keying off of ID only is the ultimate issue. Maybe I’m missing something.

The schema is basically

Module A = All account info (Not accounts module, module is custom)
Module B = Payments made by those people monthly

Import of payments occurs monthly and each payment record needs to be related One-to-Many to Each persons record without using Record ID.
If person exists in module, and is on the import, then update last paid date field for other workflow logic.
If person exists in module, but doesn’t appear on the import, then their status is changed to unpaid or inactive.
If a person doesn’t exist in the module, but appears on import, then status is changed to New Addition this month (or something similar)

I’ve been dancing around this for a while and am not a PHP expert. :frowning:

Are you aware that you can use any value for an id in SuiteCRM database, not necessarily a UUID in that format 123e4567-e89b-12d3-a456-426655440000

Maybe this way you can import to your database using whatever unique ids you already have, and it can make things easier for you?

Yes. All the data is already in place. Not really an option

I just put my huge import script in a Gist:

https://gist.github.com/pgorod/3ce7868a290df0ef4f8c9de74f12a6cd

You can throw away 75% of that code, it won’t be any use to you, but the rest will help you make your own script. As you can see, real-life imports are complex, and the ability to navigate through the complexity in PHP code is very welcome.

This needs to be defined as an entrypoint, according to dev guide. Good luck.

Will check it out.

Thank you

Looks very involved.

I appreciate the help immensely. If I may, is there any chance you can comment the parts crucial to what I’m doing or give me a hand getting through writing our own. I see what everything is doing… I think, but am still familiarizing myself with the backend of SuiteCRM. Cant wait for the rest of these master classes.

Hopefully will be able to purchase the first 2 I am missing.

Yes I know it’s too complex to serve as an initial example… but it’s what I have.

Have you read the Developer Guide, section “Working with Beans”? That covers all the most important parts.

That is helpful. Would you mind sharing custom/School/SchoolImportTurmasTable.php so I can see how these files relate to and access one another. I feel like I’m beginning to see what all is going on.

Thank you :slight_smile:

Ah, I forgot that. You can skip that part entirely. The file only has an array definition ($Turmas), so it’s basically a conversion table to allow this part to work:


		if (is_array($Turmas[$college][$turma])) {
			// 	0 "Anos", 1: "Ano", 2: "Turma", 3: "Finalistas", 5: "Curso"),
			$person->ano_c = $Turmas[$college][$turma][1];
			$person->turma_c = $Turmas[$college][$turma][2];
			$person->classe_c = $Turmas[$college][$turma][3];
		}

Just throw away anything mentioning $Turmas, and forget about that second PHP file, there’s nothing else useful for you there.

OK great. Do I require the $prefix variable in fillperson(). Im not sure how this is being used. Also is creating the xml file required. May be a dumb question.

Happily the more I go over this, the more I am able to relate PHP to CSharp, which is what I usually work in

The file Im buidling replaces Importer.php correct? The usual steps will still appear and mapping will still be functional? Theres a whole mess of import files. Lol

CSharp is a civilized language, PHP is a jungle. :slight_smile: anyway they have different uses.

  • I don’t create XML, I believe. I just read files. Anyway, I read CSV, not XML. The XML was left there because I copied from a previous example…

  • forget $prefix if you don’t need it, that’s just a field like “Mr.” and “Mrs.”

  • this file doesn’t replace any other, and you don’t call it from within the app (unless you add some link or button). I used it just as a standalone file, calling it by typing the URL by hand into the browser.

  • note that there is a LOT of crap to throw away in that gist. A basic importer of a contact can be 50 lines long. Add 6 or 7 lines for each relationship you need to create, that’s it…

Well I think I’ve got the file all written and have followed the instructions in the developer guide, however, when I navigate to the entrypoint url, which I have added everywhere I possibly can it redirects to the Dashboard page and shows only the Menus and Dashboard tab. Doesn’t load a page to import with. Am I missing something.

The entry point does NOT get created in the custom/application/Ext/EntryPointRegistry/entry_point_registry_ext.php on repair and rebuild.

Im pointing to it in both the MVC/Controller/ and in the modules//entryPoints/

Fixed blank page bad = sign in entrypoint array in MVC/Controller. Entry point still redirecting to home only showing calendar, which is what my home page is set to show. No import features though

EntryPoint is now loading into custom/application/Ext/EntryPointRegistry/entry_point_registry_ext.php

This was achieved by putting the entry point php file containing:

<?php

$entry_point_registry['exampleEntryPoint'] = array(
    'file' => 'custom/exampleEntryPoint.php',
    'auth' => true
);

into

custom/Extension/application/Ext/EntryPointRegistry

not

custom/application/Ext/EntryPointRegistry

which I did

Script still not importing… :frowning:

Not even seeing the DateTime(); Echo

I’m receiving the error below in logs

Fri Jun 15 17:21:00 2018 [25389][1][FATAL] ERROR: rmdir_recursive(): argument cache/themes/SuiteP/modules is not a file or a dir.

Permissions are set correctly

I’ve manually created the directory and repair and rebuild deletes it

This looks to be important. Have the script running finally but getting error below from:


foreach ($data as $i=>$arow)
                        {
				                 //$GLOBALS['log']->info("SchoolImporterJob: array_combine " . $i);
				                 $data[$i] = array_combine($fields, $arow);
			                  }

Warning: array_combine() expects parameter 2 to be array, boolean given in /var/www/html/afscmedbv5test/custom/wimporter/newimporter.php on line 127