Announcement

Collapse
No announcement yet.

client side : pass value from parent one2many to child

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • client side : pass value from parent one2many to child

    Hello telecastg

    i specialy ask to you because
    i can do it in hook .. but need in client side (front-end)
    How on a one2many .. when i click + button.. i can pass value from "parent" ? autofill ?
    In my sample : parent = Payroll .. so in childs .. parent is autofill out-of-box.. but i need to autofill other field from parent to child

    Certainly not hard ..

    Regards

  • #2
    Hello item
    Always glad to try to help a friend who takes the time to post solutions and help others in this forum

    So, to understand your needs:

    a) You have two entities: "ParentEntity" and "ChildEntity" linked in a One to Many relationship so "ChildEntity" has a "parentEntityId" field which corresponds to the "ParentEntity" id attribute

    b) ChildEntity is listed in a relationship panel at the ParentEntity detail view, and when you click "Create" on the ChildEntity list display, you want two fields ("LaborDate" and "ExecutionDate") in the ChildEntity to be populated with the values for the same fields in the ParentEntity.

    c) You want to be able to edit "LaborDate" and "ExecutionDate" in the ChildEntity but want the autofill values to be the same as "LaborDate" and "ExecutionDate" in ParentEntity.

    d) You want to do this at the front end instead of having to wait for the new ChildEntity to be created.

    My solution would be to use the dynamic-handler class.

    We have a similar situation in our application.

    We have an entity ServiceTicket linked in a one to many relationship with WorkOrder.

    When we are in the ServiceTicket detail display we can see what WorkOrders are linked in the relationship panel and we can create a new WorkOrder by clicking on the "Plus" sign at the relationship panel.

    The ServiceTicket entity has a varchar field "tenantCell" and the WorkOrder entity has a varchar field "customerPhone".

    When we create a new WorkOrder, we want the "customerPhone" field populated with the value of the parent ServiceTicket "tenantCell" field and we want to be able to edit this value if necessary.

    Steps:

    1) Create script client/custom/src/work-order-dynamic-handler.js (custom dynamic-handler class for WorkOrder extended from the core dynamic-handler class):
    Code:
    define('custom:work-order-dynamic-handler', ['dynamic-handler'], function (Dep) {
    
        return Dep.extend({
    
            init: function () {
                // invoke function controlFields
                this.controlFields();
                // it is not necessary for this case, but here you could also have code to invoke controlFields() again when an event takes place, like update another fiedl, etc.
            },
    
            controlFields: function () {
                // If the Work Order is new, autocomplete the field customerPhone with the value of tenantCell in the ServiceTicket parent entity
                if(this.recordView.isNew) {
                    // Get the parent entity (ServiceTicket), "serviceTicketId" is the field that links the WorkOrder to a ServiceTicket
                    var parentId = this.model.attributes.serviceTicketId;
                    var self = this;
                    // create a collection of ServiceTickets
                    this.recordView.getCollectionFactory().create('ServiceTicket', function (parentCollection){
                        // filter the collection to include only records where the field "id" is equal to the value of the WorkOrder field "serviceTicketId"
                        parentCollection.where = [
                            { type:'equals', field:'id', value: parentId }
                        ];
                        // retrieve the data from the database
                        parentCollection.fetch().then(function(){
                            // once the data has been retrieved, select the model which has an "id' equal to the "serviceTicketId" value
                            var parentObject = parentCollection.get(parentId);
                            // take the value "tenantCell" form the parent model retrieved and populate the field "customrPhone" in the WorkOrder model
                            self.model.set('customerPhone',parentObject.attributes.tenantCell);
                        });
                    });
                }
            }
        });
    });
    2) Create script custom/Espo/Custom/Resources/metadata/clientDefs/WorkOrder.json to tell Espo to call the custom dynamic-handler class when rendering a WorkOrder entity (new or otherwise)
    Code:
    {
         "dynamicHandler": "custom:work-order-dynamic-handler",
    }
    3) Clear cache and rebuild.
    Last edited by telecastg; 12-13-2020, 04:33 PM.

    Comment


    • #3
      Many Thanks telecastg
      i will try and stay tuned ..

      Best Regards

      Comment


      • #4
        telecastg great job

        Comment


      • #5
        Hello telecastg

        work like a charm
        what's incredible crm made by Yuri

        Many Thanks man

        Comment


        • telecastg
          telecastg commented
          Editing a comment
          You're very welcome :-) Espo is truly a great application generator for many projects beyond crm

      • #6
        Hello telecastg
        i ask to the front-end specialist
        that's work great.. but i need one more think : (i can do in back-end hook afterRelate, afterSave..) but need on front-end

        parent have many calculated field, i have create a action button for this on detailView of parent., .. so when we save a child (detailSmall only this can be used).. after save child, i must click the parent action button "recalculate".
        on listview, the "recalculate option is there".. but on detailView .. no.

        it's certainly possible :
        when save child .. send a request POST to api/v1/Payroll/action/massRecalculateFormula with "ids:['parentId']".
        1. path:
          /api/v1/Payroll/action/massRecalculateFormula

        Payload
        1. {ids: ["5fe10a4bd0717f7f9"]}
          1. ids: ["5fe10a4bd0717f7f9"]
        (i have see on developper mode chrome)

        So i image whe need to "listen save response of child or something so?"

        Haaa it's not enoug because .. when create child .. my button "recalculate" .. do a cutom action ..and modify child(s) from another(s) parent(s)..and recalculate them !
        it's more complicate than only a "recalculateFormula". :s
        sample : i create 1 childA from parentA ... then childA-> have clone to 3 childBCD with 3 other parentBCD, childA modified give childBCD modified and then need recalculate parentBCD.

        Regards


        Last edited by item; 12-22-2020, 09:54 PM.

        Comment


        • telecastg
          telecastg commented
          Editing a comment
          Let me make sure that I understand:

          For example when ChildA is created it triggers action recalculate for ParentA, but since ChildA also triggers a change event at Child BCD then ChildBCD should also trigger action recalculate for its parent ParentBCD.

          If this is correct, then you would need to trigger the recalculate action every time a Child entity is created or updated. Is this what you would like to accomplish ?

      • #7
        Hello telecastg , imagine we work by commission (rate).

        Parent = Payroll
        Childs = PayrollItem

        So ParentA have 100euro = sum of his PayrollItem

        ParentA must give x% commission to ParentB , ParentC, ParentD

        The commission is calculated on create.. => so ParentB, C, D have x% of ParentA => actually 100euro !

        so after... some problem come to ParentA.. and then we add a PayrollItem to ParentA with -10euro => so ParentA sum = 90euro ! so commission must be calculated with 100-10=90euro

        so .. i recalculate all ParentB, ParentC, ParentD and modify PayrollItem from child (ParentB, ParentC, ParentD) and change the amount because PayrollA => "before=100" .. "after=90" then i recalcul amount of ParentA, B, C, D

        I do that but in back-end.. with a button on ParentA .. public function actionRecalculate($params, $data, $request) in controller and after in service
        here my problem.. i will this action on save of child of parentA

        Yes.. it's strange but it's belgium
        Haaa you can say : why not create childs commission after problem parentA : because, if new ParentX come later, ParentX don't have commission.
        it's for "just-in-time" .. at begin of the month : we fixe %. and correct child at end of the month.
        % can change too in middle of the month.. so no effect if all childs is created of the begin of the month
        Last edited by item; 12-22-2020, 11:52 PM.

        Comment


        • telecastg
          telecastg commented
          Editing a comment
          So a Payroll entity (PayrollA) earns a commission based on the sum of its children PayrollItem amounts for example PayrollItemA1 is 40Euro, PayrollItemA2 is 25Euro and PayrollItemA3 is 35Euro, total = 100 Euro.

          Then PayrollA must share a percentage of that commission with PayrollB, PayrollC and PayrollD, let's assume that PayrollB gets 10% (10 Euro), PayrollC gets 20% (20Euro) and PayrollD gets 30% (30Euro).

          You calculate those distributions by clicking on a button at the Payroll detail view which triggers the actionRecalculate method in the back-end Payroll controller

          Then for some reason, the amount in PayrollItemA1 changes to 30Euro, so that changes the new commission to ParentA to 90Euro instead of 100Euro and you need to invoke the back-end actionRecalculate method again.

          So you would like to be able to invoke this method automatically every time that any PayrollItem entity is saved correct ?

          Also all you need to provide to the back-end controller as data payload from the front-end is the id of the changed/saved child object, is this right ?
          Last edited by telecastg; 12-23-2020, 07:34 AM.

        • item
          item commented
          Editing a comment
          Yes ...

          on parentA .. i add a child .. then on detailView i click : recalculate

          so i have id of ParentA.. i find related childsA .. and then loop for find related childsX form other PayrollsX .. and correct amount and save PayrollX because PayrollX have calculedField (sum/related childs)

          sample : Nurse have Manager, nurse give 3% to manager.
          nurse amount = 100e
          manager amount = 3e. (3% of 100e)

          nurse have problem = 10euro
          i add a childs : -10euro
          nurse amount become : 90e
          no i need to change the child of manager
          3e change to "3% of 90" => 2.7e
          and then i need to recalculate manager

          All work perfecly on backend.. but think user will forget click "recalculate" button...
          recalculate calcul for nurse and for many manager.

          Maybe another solution will be : onRelate, onCreate => workflow run serviceAction..

          Regards

      • #8
        Maybe another solution will be : onRelate, onCreate => workflow run serviceAction..
        I think that would work by also adding an onUpdate event as condition for the workflow (I don't use the advanced pack so I don't know how to do that but I am sure that there is a way to specify an event upon updating a record) so when you edit the Nurse record it triggers the actionRecalculate.

        The only problem that I think could be that the screen would not be immediately updated with the changes.

        Is this important for you ?. If it is, could you please post a screen shot of the detail view where you currently have the "recalculate" button ?

        Comment


        • #9
          Hello telecastg
          Voila,
          as you can see, i use your custom handler for auto-fill listViewSmal of PayrollItem

          Comment


          • #10
            Hello telecastg
            i have a little issue ..

            PHP Code:
            self.model.set('periodeName',payrollObject.attributes.periodeName);
            self.model.set('periodeId',payrollId);  // i have add this but not result 
            as periode is a link in payroll.. .. so in payrollItem, i see periodeName .. but in database i have not the ID of periode but the periodeName. (periodeName is saved)

            The problem is because periode is a link (one periode many payrool) .

            A solution

            Regards

            Comment


            • #11
              hello item

              Could you please post here the contents of your entityDefs for "Periode", "Payroll" and for "PayrollItem" so I can understand the links better and propose a solution ?

              Regards

              Comment


              • #12
                Hello telecastg
                i think you say entityDefs, clientDefs have not interesting data
                the issue is .. :
                on detail view of Payroll..
                bottomPanel : add new PayrollItem with + button
                modal detail/edit small open :
                all type of varchar or int ... is passed to small modal payrollItem

                but for periode, periodeName is passed to small modal .. you see periodeName.
                And when save... it's OK ...
                but in database, normaly we need the id of periode... but it's periodeName saved :s

                i think, we need some one more action (ajax call ?) for get the ID of periode.

                Regards


                payroll
                PHP Code:
                "payrollItems": {
                "type""hasMany",
                "foreign""payroll",
                "entity""PayrollItem",
                "audited"false,
                "isCustom"true
                },
                "periode": {
                "type""belongsTo",
                "foreign""payrolls",
                "entity""Periode",
                "audited"false,
                "isCustom"true
                }
                ....

                "payrollItems": {
                "type""linkMultiple",
                "layoutDetailDisabled"true,
                "layoutMassUpdateDisabled"true,
                "noLoad"true,
                "importDisabled"true,
                "isCustom"true
                }, 
                payrollItem
                PHP Code:

                "payroll": {
                "type""belongsTo",
                "foreign""payrollItems",
                "entity""Payroll",
                "audited"false,
                "isCustom"true
                },
                "periode": {
                "type""belongsTo",
                "foreign""payrollItems",
                "entity""Periode",
                "audited"false,
                "isCustom"true
                }

                ...

                "periode": {
                "type""link"


                Comment


                • #13
                  Hello item

                  I think that the entity schema is causing a problem.

                  Right now looks like the relationship between "Payroll" to "PayrollItem"is BOTH "One to Many" AND "Many to Many"

                  Could you clarify what is the correct relationship between "Payroll" and "PayrollItem": One "Payroll" to Many "PayrollItems" ? or Many "Payrolls" to Many "PayrollItems" ?

                  I am assuming that the correct relationship between Payroll and PayrollItem should only be One "Payroll" to Many "PayrollItems"

                  If my assumption is correct your entity schema should look like this:

                  Periode -> Payroll = One to Many (One "Periode" can have Many "Payrolls" but a "Payroll" belongs only to One "Periode")
                  Payroll -> PayrollItem = One to Many (One "Payroll" can have Many "PayrollItems" but a "PayrollItem" belongs only to One "Payroll")
                  Click image for larger version  Name:	Schema 2.PNG Views:	0 Size:	6.6 KB ID:	66635
                  Based on the above, you don't need to select "Periode" when you are creating a new "PayrollItem" entity, since "Periode" has been already defined for the parent entity "Payroll".

                  Do you just want to see "Periode.name" when you are creating a new "PayrollItem" ?

                  If this explanation doesn't help perhaps you can post screen shots of the Payroll detail view and of the new PayrollItem modal view screens to better understand how to accomplish what you want.

                  If your entity schema is different that above perhaps you could draw a diagram showing the entity schema that you want to use.
                  Last edited by telecastg; 01-23-2021, 07:09 PM.

                  Comment


                  • #14
                    Hello telecastg
                    sorry for late.. my computer was not near me.
                    if i see your draw.. i understand that where you don't understand me
                    payrollItem have a field link to periode and this is where i can't save the periode for payrollItem.



                    Click image for larger version

Name:	Screenshot 2021-01-23 at 22.14.28.png
Views:	817
Size:	690.2 KB
ID:	66645

                    Comment


                    • #15
                      I understand better thanks.

                      So do you want to be able to set the "Periode" value at "PayrollItem" even if its different from the "Periode" value in "Payroll" ? Wouldn't that make it inconsistent ?

                      For example is it acceptable that "Payroll" which is parent of "PayrollItem" has a "Periode" value of "202101" but "PayrollItem" which is child of "Payroll" have a "Periode" value of "202102" ?

                      Or do you just want to show "Periode" value inherited from "Payroll" in "PayrollItem" ?
                      Click image for larger version

Name:	screen shot.png
Views:	830
Size:	139.0 KB
ID:	66647
                      Last edited by telecastg; 01-24-2021, 02:03 AM.

                      Comment


                      • item
                        item commented
                        Editing a comment
                        Hello @telecastg

                        Periode, Payroll and 99% of PayrollItem are automaticly created by "a custom jobs".
                        User only add 1% of PayrollItem
                        User don't touch/edit/create Payroll or Periode

                        so the problem is only here

                        self.model.set('periodeName',payrollObject.attribu tes.periodeName);
                        self.model.set('periodeId',payrollId); // i have add this but not result

                        as payrollItem->periode is a "auto-complete field" who fetch data onLive.. i think we need just one more fech.. something so maybe :

                        self.model.set('periodeName',payrollObject.attribu tes.periodeName);
                        self.model.fech('periodeId') .. ?
                    Working...
                    X