beforeCreate event - how to automatically generate a field value

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bandtank
    Active Community Member
    • Mar 2017
    • 379

    beforeCreate event - how to automatically generate a field value

    In an entity called Project, I want to generate value for fields in a new item in the beforeCreate event. My project model has a field called projectNumber, which is a varchar(10). The values will be stored as YY-NNNN where YY is the two digit year (e.g., 16 for 2016) and NNNN is an incremental value starting from 0001 at the beginning of each year. For example, the first project in 2017 is 17-0001.

    In my old API, I handled this in the 'creating' method for those of you who may be familiar with Laravel. Essentially, during the creation of the object, the 'creating' method is called and it does the following operations:
    Code:
    parent::creating(function ($item) {
        $item->projectNumber = sprintf("%02d-%04d",date('y'),parent::where('year', $year)->max('number') + 1);
    });
    After that code executes, the item is inserted into the database. My problem is I don't know how to do the same thing in EspoCRM. Here's my entity controller:

    Code:
    class Project extends \Espo\Core\Templates\Controllers\BasePlus
    {
        public function beforeCreate(Entity $entity, array $data = array())
        {
            $entity->... [COLOR=#FF0000]# What goes here?[/COLOR]
        }
    }
    Any tips would be greatly appreciated.
    Last edited by bandtank; 03-27-2017, 04:13 AM.
  • tanya
    Senior Member
    • Jun 2014
    • 4308

    #2
    Hello
    At first, Controller uses for ACL and calling Service method (most common)
    If you want to modify entity before saving, do it in Hook or in Repository

    http://forum.espocrm.com/forum/devel...7-entity-hooks

    also look at this file application/Espo/Hooks/Common/NextNumber.php
    Last edited by tanya; 03-27-2017, 08:47 AM.

    Comment

    • bandtank
      Active Community Member
      • Mar 2017
      • 379

      #3
      Thanks for the reply. I only want to modify the fields when the entity is created and then never again. It looks like beforeSave will run every time the entity is saved, which isn't what I want. I actually found that thread, but I didn't know what to do with the information because I need to use beforeCreate. It looks like I need to create the beforeCreate method in my custom controller. Is that not right? From Espo/Services/Record.php:

      Code:
          public function createEntity($data)
          {
              ...
      [COLOR=#FF0000]       $this->beforeCreate($entity, $data);[/COLOR]
              ...
          }
      
          protected function beforeCreate(Entity $entity, array $data = array())
          {
      [COLOR=#FF0000]       # I should be able to override this in my entity[/COLOR]
          }

      Comment

      • tanya
        Senior Member
        • Jun 2014
        • 4308

        #4
        It looks like I need to create the beforeCreate method in my custom controller. Is that not right? From Espo/Services/Record.php:
        No
        You need to create a hook... But start you beforeSave method with
        PHP Code:
        if (!$entity->isNew()) return; 
        

        Comment

        • bandtank
          Active Community Member
          • Mar 2017
          • 379

          #5
          Actually, that doesn't seem to be the way this works. The beforeCreate method is called by Espo/Core/ControllerManager, which makes no sense to me and I can't figure out how that happens.

          I tried to do this:

          Code:
          class Project extends \Espo\Core\Templates\Controllers\BasePlus
          {
              public function beforeCreate(Entity $entity, array $data = array())
              {
                  $GLOBALS['log']->error("===========START===========");
                  $GLOBALS['log']->error("Entity = ", [$entity], $data);
                  $GLOBALS['log']->error("===========END===========");
              }
          }
          And the log says:

          Code:
          [2017-03-27 14:15:37] Espo.ERROR: E_RECOVERABLE_ERROR: Argument 1 passed to Espo\Custom\Controllers\Project::beforeCreate() must be an instance of Espo\Custom\Controllers\Entity, array given, called in C:\Repositories\psecrm\application\Espo\Core\ControllerManager.php on line 113 and defined {"code":4096,"message":"Argument 1 passed to Espo\\Custom\\Controllers\\Project::beforeCreate() must be an instance of Espo\\Custom\\Controllers\\Entity, array given, called in C:\\Repositories\\psecrm\\application\\Espo\\Core\\ControllerManager.php on line 113 and defined","file":"C:\\Repositories\\psecrm\\custom\\Espo\\Custom\\Controllers\\Project.php","line":7,"context":[]} []
          [2017-03-27 14:15:37] Espo.ERROR: ===========START=========== [] []
          [2017-03-27 14:15:37] Espo.ERROR: Entity =  [{"controller":"Project","action":"create"}] []
          [2017-03-27 14:15:37] Espo.ERROR: ===========END=========== [] []

          Comment

          • bandtank
            Active Community Member
            • Mar 2017
            • 379

            #6
            Originally posted by tanya

            No
            You need to create a hook... But start you beforeSave method with
            PHP Code:
            if (!$entity->isNew()) return; 
            
            Thanks. I see. What is the purpose of the beforeCreate method?

            Comment

            • tanya
              Senior Member
              • Jun 2014
              • 4308

              #7
              Originally posted by tanya
              Hello
              At first, Controller uses for ACL and calling Service method (most common)
              If you want to modify entity before saving, do it in Hook or in Repository
              this method check if user has access to create a record

              Comment

              • bandtank
                Active Community Member
                • Mar 2017
                • 379

                #8
                It almost works. The values are in the entity as expected, but there's nothing to click on to get into the detail view. The project number needs to be a link. I also tried using the name field, but it isn't a link either.

                Code:
                <?php
                
                namespace Espo\Custom\Hooks\Job;
                
                use Espo\ORM\Entity;
                
                class JobNumber extends \Espo\Core\Hooks\Base
                {    
                    public function beforeSave(Entity $entity)
                    {
                        if(!$entity->isNew()) { return; }
                
                        $number = "1234";
                        $year = date('y');
                
                        $entity->set("jobNumberInt",$number);
                        $entity->set("jobNumberYear",date('y'));
                        $entity->set("jobNumber",sprintf("%02d-%04d",$year,$number));
                        $entity->set("name","test");
                    }
                }
                Click image for larger version

Name:	2017-03-28_07-29-44.png
Views:	702
Size:	5.3 KB
ID:	27296

                Any ideas?

                Comment

                • bandtank
                  Active Community Member
                  • Mar 2017
                  • 379

                  #9
                  I figured it out. There's a table named 'job' already, so making an entity called 'job' caused a conflict that Espo didn't handle very well. No errors, warnings, etc. It just displayed a row in the list view of the Job tab with no link to the detail view. After I renamed the entity to something else, it worked as expected. Thanks for your help tanya.

                  Comment

                  Working...