Set "Replacement Reason" when replacing part of one to one relationship

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • onepoint0
    Member
    • Jul 2023
    • 41

    Set "Replacement Reason" when replacing part of one to one relationship

    Hi Devs,

    I am working on espo version 8.2.2.

    I have a one to one relationship set up between a Device and Camera. When I replace the camera on the device I want to make the user set a reason for replacement which I'll then save into a device history table that I have created in the backend. I have a custom saver (eg FieldProcessing with a SaverInterface) set up that creates the device history records.

    To make the user enter the replacement reason I have extended the views/modals/select-records view and instead of just closing it on select, I am opening a second modal which asks for a replacement reason (this is called in the select listener in setupList):

    Code:
    define('custom:default-filter/select-mmx-camera', ['views/modals/select-records'], function (Dep) {
    
      return Dep.extend({
    
        className: 'dialog dialog-record',
    
        backdrop: true, // 'static', true, false
    
        data: function () {
          var data = Dep.prototype.data.call(this);
          console.log('custom cam select data ',data);
          return data;
        },
    
        setup: function () {
          Dep.prototype.setup.call(this);
          // par = this.getParentView().model;
          console.log(`my camera select.js this = `,this);
        },
    
        setupList() {
    
          const viewName = this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listSelect') ||
            this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') ||
            'views/record/list';
    
          const promise = this.createView('list', viewName, {
            collection: this.collection,
            fullSelector: this.containerSelector + ' .list-container',
            selectable: true,
            checkboxes: this.multiple,
            massActionsDisabled: true,
            rowActionsView: false,
            layoutName: this.layoutName,
            searchManager: this.searchManager,
            checkAllResultDisabled: !this.massRelateEnabled,
            buttonsDisabled: true,
            skipBuildRows: true,
            pagination: this.getMetadata().get(['clientDefs', this.scope, 'listPagination']) || null,
          }, view => {
    
            this.listenToOnce(view, 'select', model => {
              if ( model.get(`isInUse`) == 1 ) {  
                Espo.Ui.error( `${model.get('name')} is attached to another Device. Please select another camera.`, true);
            } else {
              console.log(`in open reason modal`);
              this.reasonModal(model);
            }
              // this.trigger('select', model);
              //   this.close();
            });
    
            const fetch = () => {
                this.whenRendered().then(() => {
                    Espo.Ui.notify(' ... ');
                    this.collection.fetch()
                        .then(() => Espo.Ui.notify(false));
                });
            };
    
            view.getSelectAttributeList(selectAttributeList => {
              if (!~selectAttributeList.indexOf('name')) {
                  selectAttributeList.push('name');
              }
              const mandatorySelectAttributeList = this.options.mandatorySelectAttributeList ||
                  this.mandatorySelectAttributeList || [];
              mandatorySelectAttributeList.forEach(attribute => {
                  if (!~selectAttributeList.indexOf(attribute)) {
                      selectAttributeList.push(attribute);
                  }
              });
              if (selectAttributeList) {
                  this.collection.data.select = selectAttributeList.join(',');
              }
              fetch();
            });
          });
          this.wait(promise);
        },
    
        reasonModal: function (model) {
          this.createView('reasonModal', 'custom:service-replace-part-reason-dialog', {
            title: 'Add reason',
          }, view => {
            view.render();
            view.listenToOnce(view, 'done', response => {
              console.log(`get parent view `,this.getParentView());
              this.getParentView().model.set('replacementReason',response.replacementReason);
    //            model.set('replacementReason',response.replacementReason);
                console.log(`reason response = `,model);
    
                this.trigger('select', model);
                this.close();
             })
          });
        }
      });
    });​
    ​
    The second modal works and gets the reason.

    But I have two problems - one is that I can't figure out how to pass the reason back to the parent view - I have done it here in the reasonModal function using

    Code:
              this.getParentView().model.set('replacementReason',response.replacementReason);
    I can see the value in the parent view on the device model but it feels like a bad hack as it doesn't belong there.

    The second is that even when I do that, the replacement reason is not on the entity when it gets to the saver in the back end. I suspect this is because it's not a real field on the entity as defined in entityDefs, but I can't find any way to pass extra data to the saver.

    Does anyone know how I can pass the reason back to the parent view from the modal and then make it accessible in the saver in the back end?

    Cheers,
    Clare
Working...