Triggers system

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search


Execute your own code on a Dolibarr business event

To execute personalized code after a Dolibarr event (create/modify/remove a third party/invoice/product or other), Dolibarr offers a mechanism of business triggers. This mechanism allows you to personalize a work-flow to have Dolibarr business events being synchronized into another application for example. You can also use triggers to modify the behavior of Dolibarr itself: for example, to create a contract automatically when an invoice is validated, a fill a log file when a record is deleted, ...

Note that triggers is a feature for developers that is limited to:

  • business CRUD events (Create | Read | Update | Delete).
  • change of the primary status of objects

There is another feature for developers to inject custom code in the application called the Hooks system. Note, for historic reason, when you send an email, this generates also a trigger call even if this case is not among the 2 allowed.


So, to add your own code that will be triggered by a Dolibarr trigger, this is the process:

1) Copy the template trigger file htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php under the new name:

  • interface_99_all_Xxx.class.php

or

  • interface_99_modMyModule_Xxx.class.php

where Xxx is a string of your choice starting with uppercase character, 99 is the priority number for the execution of your trigger (1 being the top priority) and MyModule is the name of a module if you want that trigger is activated only if module MyModule is activated. If you want the trigger to be always active, use all instead of modMyModule. This new file must be saved inside same directory.

Note: Value you can use for modMyModule are values found in directory htdocs/core/modules.

WARNING: All those parameters are necessary for the trigger to be detected and executed! Eg: if you forget the priority number, your trigger won't be detected!

For example, you can name your new trigger file: htdocs/core/triggers/interface_99_modFacture_Myworkflow.class.php

By creating such a file with a name like the example, your new trigger file will be executed each time a Dolibarr business event occurs but only if the module Facture is enabled.

Note: If you develop a full module, you can also place the trigger file in your own module's sub-directory. Eg: if your module resides in htdocs/mymodule/, then you can place your triggers inside htdocs/mymodule/core/triggers/. But for this, you must declare the trigger into your module descriptor file (eg: /mymodule/core/modules/modMyModule.class.php). For this, add into this file triggers->1 into module_parts array:

// Defined all module parts (triggers, login, substitutions, menus, etc...) (0=disable,1=enable)
$this->module_parts = array('triggers' => 1);
//$this->module_parts = array('triggers' => 1,
//              'login' => 0,
//              'substitutions' => 0,
//              'menus' => 0);

Then disable and reenable your module. This will add a record into Table llx_const to tell Dolibarr that a trigger file must be searched in the module directory htdocs/mymodule/core/triggers/


2) Edit the file interface_99_modFacture_Myworkflow.class.php to modify its content by changing the class InterfaceMyModuleTriggers by InterfaceMyworkflow:

Then go on page Home -> Admin Tools -> About Dolibarr ->Triggers. Your new trigger file must appears in the list without any error message. This means preceding actions have been done successfully.


3) Return now to edition of file to add your own code inside function run_trigger. This function is called at each Dolibarr business event. Put your code according to events on which you want to run. Each event is identified by a code (see following chapter to get full list of codes). So you can react or no after an event by doing just a test on variable $action:

  function run_trigger($action,$object,$user,$langs,$conf)
  {
        // Put here code to execute after an action
        // The type of Dolibarr business event is stored into $action
        // Data of action are stored into object $object
        // Setup, user and language are saved into $conf, $user and $lang
        if ($action == 'COMPANY_CREATE')
        {
            dol_syslog("Trigger for action '$action' launched. id=".$object->id);
        }
        elseif ($action == 'COMPANY_MODIFY')
        {        
            dol_syslog("Trigger for action '$action' launched. id=".$object->id);
        }
        elseif ($action == 'COMPANY_DELETE')
        ...
  }

You can do what you want into this coding part, if you check that function run_trigger returns a return code according to following rule:

<0 if KO, 0 if nothing is done, >0 if OK

You can also use, inside this function, the following preinitialized variables:

  • $object is the object on which action is done (see next chapter)
  • $user is the object containing all information of Dolibarr user that realizes the business event.
  • $langs is the object that contains the user language and translations strings
  • $conf is the object that contains all the Dolibarr configuration.


4) Once your trigger file has been developed, last action is to test by using Dolibarr to execute the business event that should trigger your code. Warning, call of function run_trigger is encapsulated into a transaction. If your code return a KO code, the calling function may rollback the transaction (this depends on calling function). Add log information inside your function run_trigger to know if your code is correctly triggered and runs correctly. For this, you can use the function dol_syslog("my log message", LOG_DEBUG);

List of known triggers actions

Here is a quick view of the events that cause triggers to be searched and executed. An event is characterized by the value of the code $action, with the type of the object received in $object.

Note: The Module Agenda and Module Notification use the table Table llx c action trigger as a list of known triggers. This avoid scanning the disk for this information, but this table is just a very limited list.

In general, the trigger action code begins with the name of the module followed by the character _.

Trigger code ($action) Type object ($object)
USER_CREATE user.class.php
USER_MODIFY user.class.php
USER_DELETE user.class.php
USER_LOGIN user.class.php
USER_LOGIN_FAILED user.class.php
USER_LOGOUT user.class.php
USER_ENABLEDISABLE user.class.php
USER_NEW_PASSWORD user.class.php
USER_SETINGROUP user.class.php
USER_REMOVEFROMGROUP user.class.php
USERGROUP_CREATE (>= 12.0.0) usergroup.class.php
USERGROUP_MODIFY(>= 12.0.0) usergroup.class.php
USERGROUP_DELETE(>= 12.0.0) usergroup.class.php
GROUP_CREATE usergroup.class.php
GROUP_MODIFY usergroup.class.php
GROUP_DELETE (>= 3.3.0) usergroup.class.php
COMPANY_CREATE societe.class.php
COMPANY_MODIFY societe.class.php
COMPANY_DELETE societe.class.php
COMPANY_SENTBYMAIL (>= 3.5.0) societe.class.php
CONTACT_CREATE contact.class.php
CONTACT_MODIFY contact.class.php
CONTACT_DELETE contact.class.php
CONTACT_ENABLEDISABLE (>= 3.5.0) contact.class.php
PRODUCT_CREATE product.class.php
PRODUCT_MODIFY product.class.php
PRODUCT_PRICE_MODIFY product.class.php
PRODUCT_DELETE product.class.php
SUPPLIER_PRODUCT_BUYPRICE_MODIFY fournisseur.product.class.php
SUPPLIER_PRODUCT_BUYPRICE_CREATE fournisseur.product.class.php
ORDER_CREATE commande.class.php
ORDER_VALIDATE commande.class.php
ORDER_SENTBYMAIL commande.class.php
ORDER_DELETE commande.class.php
ORDER_MODIFY commande.class.php
ORDER_CLASSIFY_BILLED commande.class.php
ORDER_CLONE commande.class.php
ORDER_CLOSE commande.class.php
ORDER_CANCEL commande.class.php
ORDER_REOPEN (>= 3.3.0) commande.class.php
ORDER_UNVALIDATE commande.class.php
COMMANDE_ADD_CONTACT commande.class.php
COMMANDE_DELETE_CONTACT commande.class.php
COMMANDE_DELETE_RESOURCE (>= 3.6.0) commande.class.php
LINEORDER_INSERT commande.class.php
LINEORDER_UPDATE commande.class.php
LINEORDER_DELETE commande.class.php
LINEORDER_DISPATCH (>= 3.4.0) commande.class.php
ORDER_SUPPLIER_CREATE fournisseur.commande.class.php
ORDER_SUPPLIER_CLONE fournisseur.commande.class.php
ORDER_SUPPLIER_VALIDATE fournisseur.commande.class.php
ORDER_SUPPLIER_SENTBYMAIL fournisseur.commande.class.php
ORDER_SUPPLIER_APPROVE fournisseur.commande.class.php
ORDER_SUPPLIER_REFUSE fournisseur.commande.class.php
ORDER_SUPPLIER_CANCEL fournisseur.commande.class.php
ORDER_SUPPLIER_DELETE fournisseur.commande.class.php
ORDER_SUPPLIER_DISPATCH (>= 3.4.0) fournisseur.commande.class.php
ORDER_SUPPLIER_ADD_CONTACT fournisseur.commande.class.php
ORDER_SUPPLIER_DELETE_CONTACT fournisseur.commande.class.php
ORDER_SUPPLIER_DELETE_RESOURCE (>= 3.6.0) fournisseur.commande.class.php
LINEORDER_SUPPLIER_CREATE fournisseur.commande.class.php
LINEORDER_SUPPLIER_UPDATE fournisseur.commande.class.php
LINEORDER_SUPPLIER_DELETE (>= 3.6.0) fournisseur.commande.class.php
PROPAL_CREATE propal.class.php
PROPAL_DELETE propal.class.php
PROPAL_CLONE propal.class.php
PROPAL_REOPEN (>= 3.5.0) propal.class.php
PROPAL_VALIDATE propal.class.php
PROPAL_CLOSE_SIGNED propal.class.php
PROPAL_CLOSE_REFUSED propal.class.php
PROPAL_SENTBYMAIL propal.class.php
PROPAL_MODIFY propal.class.php
PROPAL_ADD_CONTACT propal.class.php
PROPAL_DELETE_CONTACT propal.class.php
PROPAL_DELETE_RESOURCE (>= 3.6.0) propal.class.php
LINEPROPAL_INSERT propal.class.php
LINEPROPAL_UPDATE propal.class.php
LINEPROPAL_DELETE propal.class.php
CONTRACT_CREATE contrat.class.php
CONTRACT_VALIDATE contrat.class.php
CONTRACT_SERVICE_ACTIVATE contrat.class.php
CONTRACT_SERVICE_CLOSE contrat.class.php
CONTRACT_DELETE contrat.class.php
CONTRAT_ADD_CONTACT contrat.class.php
CONTRAT_DELETE_CONTACT contrat.class.php
CONTRAT_DELETE_RESOURCE (>= 3.6.0) contrat.class.php
LINECONTRACT_INSERT contrat.class.php
LINECONTRACT_MODIFY contrat.class.php
LINECONTRACT_DELETE contrat.class.php
BILL_CREATE facture.class.php
BILL_MODIFY facture.class.php
BILL_CLONE facture.class.php
BILL_VALIDATE facture.class.php
BILL_UNVALIDATE (>= 3.4.0) facture.class.php
BILL_PAYED facture.class.php
BILL_UNPAYED facture.class.php
BILL_CANCEL facture.class.php
BILL_DELETE facture.class.php
BILL_SENTBYMAIL facture.class.php
FACTURE_ADD_CONTACT facture.class.php
FACTURE_DELETE_CONTACT facture.class.php
FACTURE_DELETE_RESOURCE (>= 3.6.0) facture.class.php
LINEBILL_INSERT facture.class.php
LINEBILL_UPDATE facture.class.php
LINEBILL_DELETE facture.class.php
BILL_SUPPLIER_CREATE fournisseur.facture.class.php
BILL_SUPPLIER_MODIFY fournisseur.facture.class.php
BILL_SUPPLIER_DELETE fournisseur.facture.class.php
BILL_SUPPLIER_VALIDATE fournisseur.facture.class.php
BILL_SUPPLIER_PAYED fournisseur.facture.class.php
BILL_SUPPLIER_UNPAYED fournisseur.facture.class.php
BILL_SUPPLIER_SENTBYMAIL fournisseur.facture.class.php
INVOICE_SUPPLIER_ADD_CONTACT fournisseur.facture.class.php
INVOICE_SUPPLIER_DELETE_CONTACT fournisseur.facture.class.php
INVOICE_SUPPLIER_DELETE_RESOURCE (>= 3.6.0) fournisseur.facture.class.php
LINEBILL_SUPPLIER_CREATE fournisseur.facture.class.php
LINEBILL_SUPPLIER_UPDATE fournisseur.facture.class.php
LINEBILL_SUPPLIER_DELETE (>= 3.4.0) fournisseur.facture.class.php
PAYMENT_CUSTOMER_CREATE paiement.class.php
PAYMENT_DELETE (<= 3.8) paiement.class.php
PAYMENT_CUSTOMER_DELETE (>= 3.9) paiement.class.php
PAYMENT_ADD_TO_BANK paiement.class.php
PAYMENT_SUPPLIER_CREATE paiementfourn.class.php
PAYMENT_SUPPLIER_DELETE (>= 3.9) paiement.class.php
PAYMENT_SALARY_CREATE (>= 3.6.0) paymentsalary.class.php
PAYMENT_SALARY_MODIFY (>= 3.6.0) paymentsalary.class.php
PAYMENT_SALARY_DELETE (>= 3.6.0) paymentsalary.class.php
FICHINTER_CREATE fichinter.class.php
FICHINTER_MODIFY fichinter.class.php
FICHINTER_DELETE fichinter.class.php
FICHINTER_VALIDATE fichinter.class.php
FICHINTER_SENTBYMAIL fichinter.class.php
FICHINTER_ADD_CONTACT fichinter.class.php
FICHINTER_DELETE_CONTACT fichinter.class.php
FICHINTER_DELETE_RESOURCE (>= 3.6.0) fichinter.class.php
LINEFICHINTER_CREATE (>= 3.5.0) fichinter.class.php
LINEFICHINTER_UPDATE (>= 3.5.0) fichinter.class.php
LINEFICHINTER_DELETE (>= 3.5.0) fichinter.class.php
MEMBER_CREATE adherent.class.php
MEMBER_VALIDATE adherent.class.php
MEMBER_SUBSCRIPTION adherent.class.php
MEMBER_MODIFY adherent.class.php
MEMBER_RESILIATE adherent.class.php
MEMBER_NEW_PASSWORD adherent.class.php
MEMBER_DELETE adherent.class.php
CATEGORY_CREATE category.class.php
CATEGORY_MODIFY category.class.php
CATEGORY_DELETE category.class.php
CATEGORY_LINK (>= 3.5.0) category.class.php
CATEGORY_UNLINK (>= 3.5.0) category.class.php
SHIPPING_CREATE expedition.class.php
SHIPPING_VALIDATE expedition.class.php
SHIPPING_MODIFY expedition.class.php
SHIPPING_DELETE expedition.class.php
SHIPPING_SENTBYMAIL expedition.class.php
DELIVERY_VALIDATE livraison.class.php
DELIVERY_DELETE livraison.class.php
ACTION_CREATE actioncomm.class.php
ACTION_MODIFY actioncomm.class.php
ACTION_DELETE actioncomm.class.php
ACTION_ADD_CONTACT actioncomm.class.php
ACTION_DELETE_CONTACT actioncomm.class.php
ACTION_DELETE_RESOURCE (>= 3.6.0) actioncomm.class.php
DEPLACEMENT_CREATE deplacement.class.php
DON_CREATE don.class.php
DON_MODIFY (>= 3.7.0) don.class.php
DON_DELETE (>= 3.7.0) don.class.php
LOCALTAX_CREATE localtax.class.php
LOCALTAX_MODIFY localtax.class.php
LOCALTAX_DELETE localtax.class.php
TVA_CREATE tva.class.php
TVA_MODIFY tva.class.php
TVA_DELETE tva.class.php
TVA_ADDPAYMENT tva.class.php
PROJECT_CREATE project.class.php
PROJECT_MODIFY project.class.php
PROJECT_DELETE project.class.php
PROJECT_VALIDATE project.class.php
PROJECT_CLOSE project.class.php
PROJECT_ADD_CONTACT project.class.php
PROJECT_DELETE_CONTACT project.class.php
PROJECT_DELETE_RESOURCE (>= 3.6.0) project.class.php
TASK_CREATE task.class.php
TASK_MODIFY task.class.php
TASK_DELETE task.class.php
TASK_TIMESPENT_CREATE task.class.php
TASK_TIMESPENT_MODIFY task.class.php
TASK_TIMESPENT_DELETE task.class.php
PROJECT_TASK_ADD_CONTACT task.class.php
PROJECT_TASK_DELETE_CONTACT task.class.php
PROJECT_TASK_DELETE_RESOURCE (>= 3.6.0) task.class.php
MYECMDIR_CREATE ecmdirectory.class.php
MYECMDIR_MODIFY ecmdirectory.class.php
MYECMDIR_DELETE ecmdirectory.class.php
STOCK_MOVEMENT mouvementstock.class.php
PAYBOX_PAYMENT_OK
PAYPAL_PAYMENT_OK
LINK_CREATE (>= 3.5.0) link.class.php
LINK_MODIFY (>= 3.5.0) link.class.php
LINK_DELETE (>= 3.5.0) link.class.php
OPENSURVEY_CREATE (>= 3.6.0) opensurveysondage.class.php
OPENSURVEY_DELETE (>= 3.6.0) opensurveysondage.class.php

This list may be not complete.

Manage and create a new trigger's action

To manage events other than those above, you must modify the Dolibarr code to add the following sequence in the business methods of the classes of the objects handled:

// Call trigger
$result = $this->call_trigger('CODE_TRIGGER', $user);
if ($result <0) $error++;
// End call triggers

To add context information (for example to dissociate 2 different cases called with the same Trigger code), it is possible to place this information in the properties ->context of the object on which the trigger is called. Example:

// Call trigger
$this->context = array('paramX'=>$valueX, 'anyparamofyourchoice'=>$anyvalue);
$result = $this->call_trigger('CODE_TRIGGER',$user);
if ($result < 0) $error++;          
// End call triggers

It will then be possible to add in the run_trigger method of any trigger file, an if which allows you to manage this code. The run_trigger method would then be of the form:

function run_trigger($action,$object,$user,$lang,$conf)
{
      // Put here code to execute after an action
      // The type of Dolibarr business event is stored into $action
      // Data of action are stored into object $object
      // Setup, user and language are saved into $conf, $user and $lang
      if ($action == 'XXXXX_YYYYY')
      {
          dol_syslog("Trigger for action '$action' launched. id=".$object->id);
      }
      elseif ($action == 'COMPANY_CREATE')
      {
          dol_syslog("Trigger for action '$action' launched. id=".$object->id);
      }
      elseif ($action == 'COMPANY_MODIFY')
      {        
          dol_syslog("Trigger for action '$action' launched. id=".$object->id);
      }
      elseif ($action == 'COMPANY_DELETE')
      ...
}

Please note the following before adding additional calls to triggers:

The rule is to have only 1 trigger call per business CRUD event, even when several actions are done in the same transaction. As an example: When a new ticket is created with an already assigned user, only the TICKET_CREATE trigger is called, not additionally the TICKET_ASSIGNED trigger. It is the job of the trigger to intercept also this case to scan if an assignment is done directly during creation and to execute its custom code.


Conclusion

You can in few minutes, add an interface from Dolibarr towards another system (or why not towards Dolibarr itself), with no risk since you don't touch anything to Dolibarr files. You only "added" a new trigger file inside the trigger directory. If this new interface can serve a lot of other users, you can package it into a tgz file (see page Module_development#Create_a_package_to_distribute_and_install_your_module) and submit it on the download area in section external contributions on official Dolibarr web site.

See also