add customization to an entity created

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • elbowprogrammer
    Member
    • Jan 2016
    • 58

    add customization to an entity created

    In the admin, I create a new entity and added new fields. I want to add some customization. I used http://forum.espocrm.com/forum/gener...ions-and-views as reference to create custom js files. I want to execute an algorithm when the user saves or updates, but I'm not sure how to do that. I thought,
    PHP Code:
    if(this.getAcl().checkModel(this.model,'edit')) 
    
    was it, but my code executes before I want to edit a field.
    PHP Code:
      "recordViews": {     "edit": "custom:views/bill/record/edit" } 
    
  • elbowprogrammer
    Member
    • Jan 2016
    • 58

    #2
    It works if I do it from the server side:
    PHP Code:
     namespace Espo\Custom\Repositories;     use Espo\Core\ORM\Entity;     class Bill extends \Espo\Core\Templates\Repositories\Base
    {
        protected function beforeSave(Entity $entity,array $options)
        {
            parent::beforeSave($entity,$options);             $bank = null;
            $quote = null;             if($entity->get('id') && !$entity->get('deleted')) {
                $bank = $this->getEntityManager()->getEntity('Bank', $entity->get('bankId'));
                $quote = $this->getEntityManager()->getEntity('Quote', $entity->get('quoteId'));                 if ($entity->get('bankId')) {
                    $entity->set('accountNumber', $bank->get('accountNumber'));
                    $entity->set('routingNumber', $bank->get('routingNumber'));
                }
                if ($entity->get('quoteId')) {
                    $entity->set('invoiceNumber', $quote->get('invoiceNumber'));
                    $entity->set('number', $quote->get('number'));
                    $entity->set('invoiceAmount', $quote->get('grandTotalAmount'));
                }
                if ($entity->get('invoiceAmount') != null && $entity->get('payAmount') != null) {
                    $entity->set('difference', $entity->get('invoiceAmount') - $entity->get('payAmount'));
                }
            }                 if($entity->get('id')){
                    if(!$entity->get('deleted')){
                        if($entity->get('invoiceAmount')){
                            if($entity->get('payAmount')){
                                $bank->set('balance',$bank->get('balance') - $entity->get('payAmount'));
                                $quote->set('grandTotalAmount',$quote->get('grandTotalAmount') - $entity->get('payAmount'));
                            }
                        }
                    }
                }     
        }     } 
    
    ,but it displays the valu​es after I save, not before it save. Also, I want to subtract the difference of the 'balance' in Bank entity I created and 'grandTotalAmout' in Quote entity, but I'm unable to do so. I want the user to see the changes before the user saves/update it. I can translate the code into js, but I'm not sure how to execute the line code to check when is user is creating then save, editing then save, or inline updating. php has beforeSave, and I'm not sure what is the equivalent espo has to it in js.

    Comment

    • elbowprogrammer
      Member
      • Jan 2016
      • 58

      #3
      I'm on a timetable to resolve this issue. Any assistance would be helpful. When user chooses the Bank and/or Quote in Bill entity, I want to see the fields in Bill entity set, but it only shows after I save. I also want to change the value to 'grandtotalamount' in Quote entity, and 'balance' in Bank entity (self created entity), but no changes are made. If I need to translate into javascript to see immediate results, I can do that. In javascript, I tried using this.events['input [name="bankName"] [data-action="selectLink"]'] = this.actionBank() in setup function. console.log('hello') was in the actionBank() function to run a test, and that code is execute when I click on 'Create a Bill', not when I want to select a Bank.

      Comment

      • alasdaircr
        Active Community Member
        • Aug 2014
        • 525

        #4
        In terms of getting the view to change automatically as you change values before saving:

        You can set listeners for changes in views and do calculations updating any field as you go. You'd need to get a handle to the view that controls the particular view, e.g the detail view or a field view itself. You can get this when custom creating the view in a afterRender() backbone function call. There's an example of this in the Advanced pack, but you'll need to buy it to read it. There maybe similar behaviour in the main application, I've just not seen it.

        Why your subtraction is not working : I can't see you saving the bank entity after changing the field. You need to add $this->getEntityManager->saveEntity($bank);

        Comment


        • elbowprogrammer
          elbowprogrammer commented
          Editing a comment
          I have the advanced pack. May you point me in the correct directory to take a look at the afterRender() code you are referring to?

        • alasdaircr
          alasdaircr commented
          Editing a comment
          elbowprogrammer client/modules/advanced/src/views/opportunity/fields/item-list.js

        • elbowprogrammer
          elbowprogrammer commented
          Editing a comment
          I think this is when user is updating or quickedit, not when user creates new 'bill'.
      • alasdaircr
        Active Community Member
        • Aug 2014
        • 525

        #5
        And save the $quote entity too

        Comment

        • elbowprogrammer
          Member
          • Jan 2016
          • 58

          #6
          PHP Code:
          this.listenTo(this.model,'change:bankName',function(model){
           this.getModelFactory.create('Bank',function(bank){
            bank.id = model.get('bankId');
           
            bank.fetch().done(function(){
             this.model.set({
              accountNumber: bank.get('accountNumber'),
              routingNumber: bank.get('routingNumber')
             });
             this.trigger('change');
            }.bind(this));
           },this);
          },this);           
          this.listenTo(this.model,'change:quoteName',function(model){
           this.getModelFactory().create('Quote',function(quote){
            quote.id = model.get('quoteId');
           
            quote.fetch().done(function(){
             this.model.set({
              number: quote.get('number'),
              invoiceNumber: quote.get('invoiceNumber'),
              invoiceAmount: quote.get('grandTotalAmount')
             });
             this.trigger('change');
            }.bind(this));
           
           },this);
          },this); 
          


          I have certain fields that are readonly because they will be set when user chooses the bank/quote. If user creates a 'bill', or edit the bill, or inlineedit the bill, I want user to see the changes. The directory for opportunity looks like it has to do with when user want to edit after the 'bill' was created. I though "recordviews": { "edit": "custom:views/bill/record/bill-list"} is the correct way to do it, but it isn't. I either get an error, in one particular, " ​uncaught error: can not get template. not enough data passed" (no visible data and no visible panel). Bill was entity created from admin. I haven't tested js code above, but I think this is some version from the php code above.

          Comment

          • alasdaircr
            Active Community Member
            • Aug 2014
            • 525

            #7
            I don't understand why you've not tested the code?

            If you're writing JS you need to be comfortable with using the debugger and tracing path of execution. Find out where that error message is being generated and set a breakpoint. Then examine variables, repeat until you find out what the issue is.

            That's all the advice I can give you without fully understanding the problem

            Comment

            • worldmiros
              Senior Member
              • Dec 2015
              • 120

              #8
              I might want to do the same. Would the directory file be the field name? Like in elbowprogrammer case, Espo.define('Custom:Views.Bill.Fields.BankName', 'Views.Fields.Varchar',function(Dep){}); ? And is it required to set the directory in Bill.json file? If so, how?
              Last edited by worldmiros; 03-18-2016, 03:25 PM.

              Comment

              • elbowprogrammer
                Member
                • Jan 2016
                • 58

                #9
                Is the directory I set in recordviews correct? If I set it to "edit": "directory", it shows bill >> create, twice. "detail" is when the end directory is /#Bill. I'm at a lost here. I thought I knew how to translate the php code in js, but I'm not sure how to set the directory in the json file, or if I should set a directory in the json file, or what the dependency is.

                Comment

                • elbowprogrammer
                  Member
                  • Jan 2016
                  • 58

                  #10
                  yuri I created a directory, 'client/custom/src/views/bill/fields/account-number.js'. I added console.log to see if I get any output but nothing happens. What is the correct way to set the directory, so I can customize how to set certain fields when user chooses a entity (bank and/or quote)?
                  PHP Code:
                   Espo.define('Custom:Views.Bill.Fields.AccountNumber','Views.Fields.Varchar', function (Dep) {         return Dep.extend({             setup: function () {
                              Dep.prototype.setup.call(this);                 console.log("setup function");
                              console.log(this.model.has('accountNumber'));
                          },             afterRender: function () {
                              Dep.prototype.afterRender.call(this);                 console.log("afterRender function");
                              console.log(this.model.has('accountNumber'));
                          }     
                      });
                  }); 
                  

                  Comment

                  • alasdaircr
                    Active Community Member
                    • Aug 2014
                    • 525

                    #11
                    You need to assign the view in the clientDef for the entity. Start by greping the source code for shared names between the backend and frontend. That way you'll learn how the system works together.

                    Be aware that / and . delimited namespaces are interchangeable.

                    eg. Record.Panels.ActivitiesEvents == record/panels/activities-events

                    Comment

                    • elbowprogrammer
                      Member
                      • Jan 2016
                      • 58

                      #12
                      I figured it out. I used account.js in Quote as an example, as well the quote json file.

                      Comment

                      Working...