Переопределение метода save при сохранении карточки Контрагента

Добрый день.
Задача: при сохранении карточки контрагента производить проверку - а не существует ли уже в системе контрагента с таким же значением поля UsrParametr1.
Я переопределила метод save() в карточке контрагента. Произвожу поиск с помощью EntitySchemaQuery - если в качестве результата мне вернулось кол-во записей > 1, значит запись с таким UsrParametr1 существует и я просто вывожу сообщение и не сохраняю карточку контрагента.
Но если же же записей Подскажите, как решить данную проблему?

Переопределенный метод save():

save: function() {
        var param = this.get("UsrParametr1");
        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: "Account"
        });
        esq.addColumn("UsrParametr1", "UsrParametr1");
        var filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrParametr1", param);
        esq.filters.add("filter", filter);
        esq.getEntityCollection(function(result) {
                if (!result.success) {
                        this.showInformationDialog("Ошибка");
                        return;
                }
               
                if (result.collection.collection.items.length > 1)
                {
                        this.showInformationDialog("Нельзя сохранить");
                        return;
                }
                this.callParent(arguments); // не отрабатывает, появляется ошибка
        }, this);
}

Нравится

4 комментария

Добро пожаловать в мир асинхронных вычислений!
Для наглядности:

esq.getEntityCollection(callback, scope);

т.е программа заходит в функцию save, бежит до esq.getEntityCollection, и после него функция save завершается. Далее спустя некоторое время приходит callback, вызывается функция с параметром result

function(result) {
                if (!result.success) {....

Беда в том, что внутри неё ни о каком callParent() и речи быть не может. (ибо вы находитесь внутри самописной функции, у неё нет родителя для вызова).

В качестве дико кривого варианта:

save: function(parameter) {
if (!parameter) {this.checkField()}
else {this.callParent(arguments)}
}
 
checkField: function() {
//тут esq запрос и в callback-е, если все условия сходятся (записей < 1 в вашем случае), вызываете this.save(true);
}

или

сделать по-умному: в объекте создать событийный подпроцесс (перед сохранением или проверка записи, тут надо примеры в конфигурации посмотреть), в подпроцессе проверять условия и в зависимости от них принимать решение... Но это все скучно, к тому же придется кодить на C#.

Как-то так. Костыли - наше все.

Лучше в Validation это делать, наверное

Добрый день. В вашем случае надо переопределить getParentMethod, чтобы callParent не вызывался.
Рабочий код будет выглядеть следующим образом:

getParentMethod: function() {
	var method,
		superMethod = (method = this.getParentMethod.caller) && (method.$previous ||
			((method = method.$owner ? method : method.caller) &&
			method.$owner.superclass[method.$name]));
	return superMethod;
},
 
 
save: function() {
		var parentSave = this.getParentMethod();
		var parentArguments = arguments;
 
        var param = this.get("UsrParametr1");
        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: "Account"
        });
        esq.addColumn("UsrParametr1", "UsrParametr1");
        var filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrParametr1", param);
        esq.filters.add("filter", filter);
        esq.getEntityCollection(function(result) {
                if (!result.success) {
                        this.showInformationDialog("Ошибка");
                        return;
                }
 
                if (result.collection.collection.items.length > 1)
                {
                        this.showInformationDialog("Нельзя сохранить");
                        return;
                }
                //this.callParent(arguments); // не отрабатывает, появляется ошибка
				parentSave.apply(this, parentArguments);
        }, this);
}

Елена, в Вашем первоначальном коде, достаточно в коллбэкке esq-запроса, вызывать не this.callParent(argumеnts); а непосредственный метод "save" у контекста. При необходимости сохранив в текущем контексте аргументы изначально передаваемые в метод, и установив специальный флаг реагируя на повторный вызов.

save: function() {
    //Проверка на повторный вызов из асинхронной функции запроса.
    if (this.saveRecallFlag) {
        //сбросим флаг повторного вызова
        this.saveRecallFlag = false;
        //стандартное сохранение
        this.callParent(arguments);
    } else {
        //Если нет - выполняем логику:
        var param = this.get("UsrParametr1");
        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: "Account"
        });
        esq.addColumn("UsrParametr1", "UsrParametr1");
        var filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrParametr1", param);
        esq.filters.add("filter", filter);
        //Перед асинхронным вызовом, сохраним набор аргументов с которым был вызван метод в текущем контексте
        //Мы именно клонируем массив, т.к. в момент вызова асинхронной функции, псевдомасив arguments будет
        //содержать параметры вызова коллбэка.
        this.saveArgumentsRecallBuff = _(arguments).clone();
        //Установим в текущий контекст специальный флаг, который позволит проигнорировать логику проверки
        //при повторном вызове
        this.saveRecallFlag = true;
        esq.getEntityCollection(function(result) {
                if (!result.success) {
                        this.showInformationDialog("Ошибка");
                        return;
                }
 
                if (result.collection.collection.items.length > 1)
                {
                        this.showInformationDialog("Нельзя сохранить");
                        return;
                }
                this.save(this.saveArgumentsRecallBuff); // не отрабатывает, появляется ошибка
        }, this);
    }
}
Показать все комментарии