Динамический запрос crm rest builder для отношения многих ко многим

1

Мне нужно установить поле поиска контракта в crm на основе выбранной учетной записи и бизнес-единицы. Это отношение много-много в crm. Лучший способ, я могу думать, сделать это - создать 2 запроса /api-звонки (используя crm rest builder), чтобы иметь возможность сделать это на основе критериев. первый запрос обращается к таблице пересечений (таблица счетов-контрактов), чтобы возвращать все контракты на основе учетной записи, а секундам нужно дополнительно фильтровать результаты, перебирая все результаты первого запроса и подсчитывая все контракты которые соответствуют выбранному бизнес-единице. теперь проблема im заключается в том, что я использовал массив, чтобы выталкивать все значения из первого запроса, чтобы иметь возможность зацикливаться во втором. Однако массив, который я создал, не достигает цикла for, поэтому второй запрос не выполняется

function populateContractLookup() {
    var buisnessUnitId = getFieldValue("hc_businessunit");
    var worksiteId = getFieldValue("hc_worksite")[0].id;
    worksiteId = stripCurlies(worksiteId);


    if (buisnessUnitId != null) {
        buisnessUnitId = stripCurlies(buisnessUnitId[0].id);
        var condition = "_hc_businessunit_value eq " + buisnessUnitId + " and";

    }
    else {
        condition = "";
    }//to be able to count the how many contracts that would hav gotten populated to contract lookup field
    var validcontractid;
    var contractCount = 0;
    var contractArray = [];
    //this query gets all contracts based on account
    var req = new XMLHttpRequest();
    req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, true);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 200) {
                var results = JSON.parse(this.response);
               // Xrm.Utility.alertDialog(results.value.length);

                for (var i = 0; i < results.value.length; i++) {
                    var contractid = results.value[i]["contractid"];
                   // Xrm.Utility.alertDialog(contractid);
                    contractArray.push(contractid);


                }
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }// Xrm.Utility.alertDialog(contractArray.length) prints to the screen here
    };
    req.send();
    //query to furthr filter the above query to get all contracts based on the buisness unit

    //Xrm.Utility.alertDialog(contractArray.length);//not printing to screen
    for (var i = 0; i < contractArray.length; i++) {

        Xrm.Utility.alertDialog("were in the loop"); //not reaching this loop
        var req = new XMLHttpRequest();
        req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts?$select=contractid&$filter=contractid eq " + contractArray[i] + " and  _hc_businessunit_value eq " + buisnessUnitId, true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
        req.onreadystatechange = function () {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 200) {
                    var results = JSON.parse(this.response);
                    Xrm.Utility.alertDialog(results.value.length);
                    for (var i = 0; i < results.value.length; i++) {
                        contractCount++;
                    }
                } else {
                    Xrm.Utility.alertDialog(this.statusText);
                }
            }
        };
        req.send();
    }
}

. Я думаю, почему я не могу получить доступ к моему приходу?

Теги:
dynamics-crm
microsoft-dynamics
crm

2 ответа

2

Ваш первый запрос является асинхронным. Код после первого req.send() выполняется немедленно, тогда как вам нужно, чтобы результат вашего первого запроса был возвращен до выполнения любого другого кода.

Поэтому вам необходимо перенести второй запрос, который зависит от результата первого, в функцию обратного вызова. Затем вы вызываете эту функцию обратного вызова при успешном обратном вызове вашего первого запроса.

См. qaru.site/questions/65486/... для получения информации о функциях обратного вызова.

В стороне, ваш второй запрос не будет работать. Вы пытаетесь выполнить запрос один раз для каждого контракта, который был получен. То, что вы хотите сделать, - это создать свой фильтр OData, итерации по массиву contractArray и записи '(contractid eq ' + contractArray[i] + ') or'//...

В качестве другой стороны рассмотрите возможность использования агрегата FetchXML для подсчета записей.


Ваш код может выглядеть примерно так:

var buisnessUnitId = getFieldValue("hc_businessunit");
var worksiteId = getFieldValue("hc_worksite")[0].id;

function populateContractLookup() {        
    worksiteId = stripCurlies(worksiteId);

    if (buisnessUnitId != null) {
        buisnessUnitId = stripCurlies(buisnessUnitId[0].id);
        var condition = "_hc_businessunit_value eq " + buisnessUnitId + " and";
    }
    else {
        condition = "";
    }//to be able to count the how many contracts that would hav gotten populated to contract lookup field
    var validcontractid;
    var contractCount = 0;
    var contractArray = [];
    //this query gets all contracts based on account
    var req = new XMLHttpRequest();
    req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, true);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 200) {
                var results = JSON.parse(this.response);
               // Xrm.Utility.alertDialog(results.value.length);

                for (var i = 0; i < results.value.length; i++) {
                    var contractid = results.value[i]["contractid"];
                    // Xrm.Utility.alertDialog(contractid);
                    contractArray.push(contractid);                        
                }
                // Call your callback function.
                countContracts(contractArray);
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }// Xrm.Utility.alertDialog(contractArray.length) prints to the screen here
    };
    req.send();
}    

Функция обратного вызова (хотя, как я уже упоминал выше, требуется переписывание):

function countContracts(contractArray) {
    for (var i = 0; i < contractArray.length; i++) {
        Xrm.Utility.alertDialog("were in the loop"); //not reaching this loop
        var req = new XMLHttpRequest();
        req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/contracts?$select=contractid&$filter=contractid eq " + contractArray[i] + " and  _hc_businessunit_value eq " + buisnessUnitId, true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
        req.onreadystatechange = function () {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 200) {
                    var results = JSON.parse(this.response);
                    Xrm.Utility.alertDialog(results.value.length);
                    for (var i = 0; i < results.value.length; i++) {
                        contractCount++;
                    }
                } else {
                    Xrm.Utility.alertDialog(this.statusText);
                }
            }
        };
        req.send();
    }
}
0

Вы можете попробовать переключить первый вызов как синхронный, изменив флаг, как показано ниже, и результат будет доступен сразу перед вторым вызовом.

req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/hc_account_contractset?$select=contractid&$filter=accountid eq " + worksiteId, false);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню