Вопрос

Суммирование полей детали

Добрый день! В разделе продажи есть вкладка продукты, где размещена деталь продукты/услуги в продаже. Здесь каждый продукт имеет стоимость. Также есть вкладка данные о продаже и там есть поле сумма продажи в которое необходимо просуммировать стоимость для всех продуктов из предыдущей вкладке. Подскажите метод как это можно реализовать.



 

Нравится

8 комментариев

Добрый день, Вадим!

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

Если вопрос в том, как реализована логика пересчета поля "Сумма продажи" на основании суммы всех продуктов в детали "Продукт в продаже", то данная логика записана на объекте [OpportunityProductIneterst] в методе "CalckOpportunityAmmount" :

var oppotrunityAmountSelect = new Select(UserConnection)

    .Column("Amount")

    .From("OpportunityProductInterest")

    .Where("OpportunityId").IsEqual(Column.Parameter(opportunityId)) as Select;

double opportunityAmount = 0.0;

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

    using (IDataReader dr = oppotrunityAmountSelect.ExecuteReader(dbExecutor)) {

        while (dr.Read()) {

            if(!dr.IsDBNull(0)){

                opportunityAmount += (double)UserConnection.DBTypeConverter.DBValueToDecimal(dr[0]);

            }

        }

    }

}

//далее идет код обновления продажи после пересчета (здесь же в объекте): 



var update = new Update(UserConnection, "Opportunity")

        .Set("Amount", Column.Parameter(opportunityAmount))

        .Where("Id").IsEqual(Column.Parameter(opportunityId));

    update.Execute();

Также, на всякий случай прикрепляю код пересчтеа суммы и цены именно в детали "Продукт в продаже" для каждого отдельного продукта:

* Recalculates products amount in opportunity.

                     * @private

                     */

                    recalculateAmount: function() {

                        var price = this.get("Price");

                        var quantity = this.get("Quantity");

                        if (price && quantity) {

                            this.set("Amount", price * quantity);

                        }

                    },

                    /**

                     * Recalculates product price.

                     * @private

                     */

                    calculatePrice: function() {

                        var product = this.get("Product");

                        if (this.Ext.isEmpty(product) || this.Ext.isEmpty(product.Currency)) {

                            return;

                        }

                        MoneyModule.onLoadCurrencyRate.call(this, product.Currency.value, null, function(item) {

                            var price = (product.Price * item.Division) / (item.Rate);

                            this.set("Price", price);

                        });

                    },

Большое спасибо за ответ. А чтобы реализовать такую же логику, но для своей детали, то нужно поступать подобным образом или же существует проще реализация?

Генкал Вадим,

Если вам не нужно это поле оперативно отображать в карточке, то можно сделать в простом БП по событиям добавления/редактирования/удаления записей в объекте продукты/услуги

Владимир Соколов,

Реализовал для даного обьекта событие 

ProductInOpportunitySaving в таком виде: добавил процес(скрин), а в элемент script task такой код: var opportunityId = Entity.GetTypedColumnValue<Guid>("OpportunityId");

var oppotrunityAmountSelect = new Select(UserConnection)

    .Column("Amount")

    .From("CHProductsAndServicesInOpp")

    .Where("OpportunityId").IsEqual(Column.Parameter(opportunityId)) as Select;

double opportunityAmount = 0.0;

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

    using (IDataReader dr = oppotrunityAmountSelect.ExecuteReader(dbExecutor)) {

        while (dr.Read()) {

            if(!dr.IsDBNull(0)){

                opportunityAmount += (double)UserConnection.DBTypeConverter.DBValueToDecimal(dr[0]);

            }

        }

    }

}

var update = new Update(UserConnection, "Opportunity")

        .Set("Amount", Column.Parameter(opportunityAmount))

        .Where("Id").IsEqual(Column.Parameter(opportunityId));

    update.Execute();

return true;

После публикации поле не считается. Cистема выдает ошибку: Значение с именем "OpportunityId" не найдено

Saving срабатывает до записи в базу. Соответственно, запрос select выберет ещё старое значение. После сохранения срабатывает событие Saved, лучше на нём.

Ну и перебор в цикле — не лучший вариант, если на детали много записей. Можно сразу написать запрос с sum.

Зверев Александр,

Спасибо за ответ. Но почему выдает ошибку: 

"Значение с именем "OpportunityId" не найдено" когда я изменяю записи в детали. Судя по вашему ответу у меня должно было просто остаться старое значение. Но по факту система не находит OpportunityId. Подскажите, с чем это может быть связано?

Возможно, там ещё пусто. Или поле не так называется. Нужно отлаживаться.

Разобрался. Проблема была в именовании поля.

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