Писал уже на эту тему, вот решил и код приложить. Суть проблемы - некоторые неточности в штатной работе подбора продуктов в мастере в sales commerce и enterprise может потенциально привести к указанию в заказе неправильных цен, неправильных ставок НДС или продать то, что данному клиенту вообще продать нельзя.
Как сделано в коробке:
1. Настраиваете прайсы, один делаете базовым
2. Настраиваете разные цены для разных продуктов, включая валюты и ставки НДС
3. Открываете мастер подбора и несколько удивляетесь, потому что:
- отображается та цена, которая соответствует текущему установленному в настройках прайсу
- у продуктов, для которых не установлена эта цена, отображается некая другая цена, если используется несколько валют и ставок НДС - ясно, к чему это все приведет.
По моему мнению данное поведение свидетельствует о том, при проектировании этой логики не все было продумано как следует, поэтому будем править, желательно малой кровью :)
Описано на примере заказа, но в принципе должно работать и в фактуре. То, что мы сделали в качестве обходного пути имеет несколько вводных:
1. У нас прайс-лист задается в лоб в заказе непосредственно. Если нужно задавать в клиенте, то вместо получения значения прайлиста в заказе нужно его из клиента тащить (лучше в заказ, тогда ничего нашего править не придется.
2. При изменении прайса в заказе автоматический перерасчет не осуществляется - правьте руками в позициях :)
Теперь суть изменений:
1. Основным модулем, отвечающим за работу мастера подбора является ProductSelectionViewModel. Чтобы его перестроить как нам надо, создаем замещающий пользовательский модуль, в качестве родителя указываем этот самый ProductSelectionViewModel и копируем туда все целиком из оригинала, включая Dependencies, картинки и строки локализации. Внимание - строки локализации должны быть переименованы в коде, иначе не подтянутся значения строчек. Например, в оригинале было PriceLabel: resources.localizableStrings.PriceCaption, у нас будет PriceLabel: resources.localizableStrings.ChlidPriceCaption, соответственно нужно создать новую строку локализации ChildPriceCaption, скопировать туда из оригинала текст.
2. Нужно загрузить туда заново иконки, их всего две - каталог и корзина. Это просто - сохраните в браузере и потом загрузить в наш модуль.
3. Добавляем в заказ поле "Прайслист" (справочник, прайслист), обязательное.
4. Теперь надо модифицировать код. В частности:
- в функции init: function(config) закомментить строку
this.set("BasePriceList", config.BasePriceList);
- присвоение значения this.set("BasePriceList") перетаскиеваем в функцию requestMasterEntityData: function(callback):
добавляем
select.addColumn("PriceList"); // PriceList - имя поля в объекте
добавляем
this.set("BasePriceList", result.entity.get("PriceList"));
теперь у нас есть значение параметра схемы BasePriceList, который соответствует прайсу в заказе.
дальше переопределяем то, что должно вывестисть в мастере подбора:
- в функции loadGridData: function() переносим строку
var basePriceList = this.get("BasePriceList");
над
this.initQueryColumns(esq, basePriceList.value);
в вызов которой добавляем параметр basePriceList.value
- в самой функции initQueryColumns
вставлем новый параметр pricelist в объявление функции:
initQueryColumns: function(esq, pricelist)
комментим вот эти строки:
// esq.addColumn("Price");
// esq.addColumn("Currency");
// esq.addColumn("Tax");
вместо них вставляем
esq.addColumn("[ProductPrice:Product:Id].Price", "Price");
esq.addColumn("[ProductPrice:Product:Id].Currency", "Currency");
esq.addColumn("[ProductPrice:Product:Id].Tax", "Tax");
добвляем фильтр по прайсу (хотим только те продукты, которые имеют этот прайс)
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "[ProductPrice:Product:Id].PriceList", pricelist));
функция готова :)
На этом этапе при нажатии на + в заказе у нас отобразится правильный список продуктов в правильными ценами. Проблема в том, что уже все работает, но при сохранении в позицию "продукт в заказе" пропишется базовый прайс.
Исправляем этот недочет:
- в функции saveSelectedProducts находим фрагмент:
/* if (item.get("PriceList")) {
insert.setParameterValue("PriceList", item.get("PriceList").value, Terrasoft.DataValueType.GUID);
} else if (this.get("BasePriceList")) {
insert.setParameterValue("PriceList", this.get("BasePriceList").value, Terrasoft.DataValueType.GUID);
}*/
и комментим его. Как я понял, у этого куска кода есть неслабая проблема - item.get("PriceList") при сохранении позиции из мастера всегда null, чтобы это побороть пишем "в лоб":
// in the original script there's no pricelist chosen, so we've pushed it from master entity
insert.setParameterValue("PriceList", this.get("BasePriceList").value, Terrasoft.DataValueType.GUID);
В принципе все :) НДС и валюты тоже тянутся, понятное дело.
еще мы от греха добавили
basePriceListProductEsq.addColumn("[ProductPrice:Product:Id].PriceList", "PriceList"); //new line, isn't required
в запрос для новой позиции в функции loadGridData, но особой разницы не заметили.
И последнее - на фактуре (счете) не проверяли, но по идее, если туда тоже вставить поле "Прайс-лист" работать должно.
Во вложении исправденный модуль для 7.8.x - 7.10.x