Изменить значение поля в карточке редактирования раздела при добавлении записи на деталь.

Здравствуйте!
Такой вопрос:

Есть карточка редактирования раздела "Заявление на перс. дни", у неё есть деталь "Персональный день в заявлении", при добавлении или изменении значения в которой - требуется изменить значение числового поля Кол-во(дней) указать количество выбранных дней добавленных на деталь. (в атаче наглядно)

При изменении\добавлении с детали "Персональных дней" мы меняем на уровне обьекта Entity значение У заявления (тоесть у записи открытой карточки), и само собой разумеется - нужно установить соответствующее на текущей открытой карточке Заявления.

Для этого в карточке редактирования "Заявления на перс. день" после PageOnLoadCompleete я сохраняю в сессии Uid процесса так

var session = System.Web.HttpContext.Current.Session;
if (session["FreeDayStatementPageProcessUid"] == null) {
        session.Add("FreeDayStatementPageProcessUid", Page.Process.InstanceUId);
}

В карточке редактирования детали "Персональные дни" на нажатие кнопки Ok я вытаскиваю из сессии id процесса и высылаю ему сообщение, и сообщение то приходит. Код:

var session = System.Web.HttpContext.Current.Session;
string freeDayStatementPageProcessUId = (string) session["FreeDayStatementPageProcessUid"];           
if (!string.IsNullOrEmpty(freeDayStatementPageProcessUId ))
{
        var process = UserConnection.ProcessEngine.FindProcessByUId(freeDayStatementPageProcessUId );
        if (process != null)
        {
                process.ThrowEvent(process.InternalContext, "FreeDayInFreeDayStatementMessage");
        }
}
return true;
;

И вот тут начинается самое интересное:
В процессе родительского окна (то есть Заявления) я пытаюсь установить значение полю. А поля нет т.к Page = null (в атаче картинка). При этом context и this это тот нужный процесс. Пробовал сохранять Page в параметр отдельно, и тоже Null. Также пытался передавать в ThrowEvent ранее сохраненный контекст Заявления - всё безрезультатно. До контролов не добраться.
Подскажите что я делаю не так?

Сразу скажу что реализация не конечная это своего рода проверка метода.

Нравится

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

Похожее делали с помощью клиентской логики.

На PageLoadComplete детали (у нас DiscountGridPage):

AddPageRefreshFunctionality(Page);

функция:

        public static void AddPageRefreshFunctionality(DiscountGridPageSchemaUserControl Page) {
const string methodName = "setNewColumnValues";
            var script = "";
script += @"window."+methodName+ @" = function (newValues){
    var ds = " + Page.OpportunityDataSource.ClientID + @";
    ds.suspendAjaxEvents();
	for(var columnName in newValues){
		var column = ds.getColumnByName(columnName);
		if (column) {
			ds.setColumnValue(columnName, newValues[columnName]);
		}
	}
    ds.resumeAjaxEvents();
};
window.ReloadOpportunityInfo = function () {
    var layout = " + Page.CustomerDiscountControlLayout.ClientID + @";
    layout.callPageMethod('ThrowEvent',{signalName:'RefreshData'});
};";
            script = ";(function(){" + script + "})();";
            Page.AddScript(script);
        }

На детали на событии RefreshData вызываем функцию с параметрами Page и SelectedNodePrimaryColumnValue.
Она создаёт Entity основного раздела с новыми значениями полей:

 public static void OnDiscountFieldsChanged(DiscountGridPageSchemaUserControl Page, Guid opportunityId) {
            var row = FetchCurrentOpportunity(Page.UserConnection, opportunityId, true);
            var isChangesOnCardFlag = false;
            if (row.CDStockDiscountUse != (bool) Page.CDStockDiscountUseCheckBox.Value) {
                row.CDStockDiscountUse = (bool)Page.CDStockDiscountUseCheckBox.Value;
                isChangesOnCardFlag = true;
            }
            if (row.CDConsideredKS != (bool)Page.CDConsideredKSCheckBox.Value) {
                row.CDConsideredKS = (bool)Page.CDConsideredKSCheckBox.Value;
                isChangesOnCardFlag = true;
            }
            if (row.CDConsideredSK != (bool)Page.CDConsideredSKCheckBox.Value) {
                row.CDConsideredSK = (bool)Page.CDConsideredSKCheckBox.Value;
                isChangesOnCardFlag = true;
            }
            if (isChangesOnCardFlag) {
                OpportunityLogicHelper.UpdateFinalDiscount(row);
            }
            UpdateOpportunityFields(Page, row);
        }

Тут в предпоследней строке вызывается функция, которая делает Update в базе для полей в записи в разделе (не показана). Именно Update — чтобы не сработали события на объекте.
А в последней — обновление в карточке, о котором Вы спрашивали:

        private static void UpdateOpportunityFields(DiscountGridPageSchemaUserControl Page, Opportunity opportunity) {
            if (opportunity != null) {
                var info = AmountColumnns.ToDictionary(s => s, opportunity.GetColumnValue);
                var script = "if (window.setNewColumnValues) { window.setNewColumnValues(" + JsonConvert.SerializeObject(info) + "); }";
                script = ";(function(){" + script + "})();";
                Page.AddScript(script);
            }
        }

Там ещё много другой логики, что-то мог и пропустить.

Решение в лоб повесил на события детали DataSourceRemoved, DataSourceLoadRowsResponseRegistered:

var durationEditControl= ControlUtilities.FindControl(Page.AspPage.Controls[0], "DurationEdit", true) as Terrasoft.UI.WebControls.Controls.FloatEdit;
 
if (durationEditControl != null && SelectedNodePrimaryColumnValue != null) {
	var freeDayStatementEntity = new Terrasoft.Configuration.FreeDayStatement(UserConnection); 
	Guid freeDayStatementId = Guid.Empty;
        freeDayStatementId = new Guid(SelectedNodePrimaryColumnValue.ToString());		
	if (freeDayStatementEntity.FetchFromDB(freeDayStatementId)) {
		durationEditControl.SetValue(freeDayStatementEntity.GetTypedColumnValue<decimal>("Duration"));
	} 
}
return true;

В объекте Заяление на перс дни, при добавлении на деталь персональных дней отрабатывает логика в entity которая меняет значение той записи для которой добавили дни.

Можно и так. Возможно, стоит одновременно менять значение поля и в БД (с использованием Entity или Update), чтобы не возникло расхождение, если пользователь поменяет на детали и нажмёт в карточке отмену. Лучше даже Update, чтобы возможный БП по таблице раздела сработал только раз, при нажатии ОК.

"Зверев Александр" написал:

Можно и так. Возможно, стоит одновременно менять значение поля и в БД (с использованием Entity или Update), чтобы не возникло рахождение, если пользователь поменяет на детали и нажмёт в карточке отмену. Лучше даже Update, чтобы возможный БП по таблице раздела сработал только раз, при нажатии ОК.

Да именно так и делаю через entity на вставку или удалении в детали срабатывает изменение записи.

Показать все комментарии