В торговой практике нередко возникает задача, когда в рамках одной сделки с покупателем необходимо продать товары и услуги, номинированные в разных валютах (например, импортный товар в USD или EUR, а сопутствующую доставку и сборку — в RUB), при этом клиент желает видеть все позиции в едином документе и оплачивать их в рублях. Рассмотрим, с какими сложностями сталкивается разработчик при попытке доработать табличную часть документа ЗаказКлиента, почему прямое добавление валюты в строки ломает типовые подсистемы и как решить задачу корректными архитектурными методами.
Проанализируем устройство подсистемы взаиморасчетов современных версий конфигураций на базе архитектуры ERP / УТ 11. Попытка добавить реквизит Валюта непосредственно в табличную часть Товары документа ЗаказКлиента влечет за собой глубокие системные конфликты:
РасчетыСКлиентами, РасчетыСКлиентамиПоСрокам) жестко привязан к измерению АналитикаУчетаПоПартнерам и ключевому реквизиту ОбъектРасчетов. Валюта взаиморасчетов всегда определяется на уровне договора или документа в целом. Если один и тот же объект расчетов попытаться двигать по разным валютам, нарушится целостность регистра и баланс расчетов.ЗакрытиеМесяца выполняет автоматическую переоценку валютных остатков. Алгоритмы переоценки ожидают однозначного соответствия между объектом расчетов и его валютой. При модификации проводок регламентное задание распределения и переоценки будет падать с ошибками либо формировать некорректный финансовый результат.РеализацияТоваровУслуг, ПоступлениеБезналичныхДенежныхСредств, ВзаимозачетЗадолженности, СверкаВзаиморасчетов. Объем трудозатрат на сопровождение таких изменений при регулярных обновлениях конфигурации становится нерентабельным.EnterpriseData с конфигурацией 1С:Бухгалтерия предприятия, а также электронный документооборот (форматы УПД и счетов-фактур ФНС) требуют единой валюты для всего документа (строка 7 бланка счета-фактуры). Смешанный документ невозможно отправить контрагенту по ЭДО или бесшовно выгрузить в бухгалтерский контур.Если цель компании заключается в том, чтобы зафиксировать прайс-лист в валюте поставщика, но итоговую задолженность и отгрузочные документы формировать в рублях, разберем типовую схему мультивалютного ценообразования. В конфигурации 1С:Управление торговлей валюта цен и валюта документа могут различаться штатно:
ВидыЦен: для товаров укажем валюту цен USD или EUR, для услуг — RUB.ЗаказКлиента зададим валюту расчетов — RUB.Если менеджеру требуется видеть валюту прайс-листа непосредственно перед глазами, решим это доработкой формы через механизм расширений. Добавим в форму документа пользовательские реквизиты строк ВалютаЦены и ЦенаВВалюте, которые будут носить исключительно информационный (справочный) характер:
&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
Если СтрокаТЧ <> Неопределено Тогда
// Получаем исходную валюту прайса и пересчитываем в рублевую цену документа
РассчитатьЦенуПоКурсуНаСервере(СтрокаТЧ.Номенклатура, Объект.Дата, СтрокаТЧ.ВалютаЦены, СтрокаТЧ.ЦенаВВалюте, СтрокаТЧ.Цена);
СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
КонецЕсли;
КонецПроцедуры
При таком подходе ядро проведения документа остается полностью типовым, закрытие месяца работает штатно, а взаиморасчеты ведутся строго в рублях.
Если клиенту действительно принципиально фиксировать валютный долг по импортным позициям отдельно от рублевых услуг (например, по валютным позициям должна возникать курсовая разница до момента полной оплаты), оптимальным решением является разбиение сделки на несколько типовых документов.
Чтобы менеджерам не приходилось вручную дублировать информацию, спроектируем интерфейсную обработку или составной документ-обертку. Разберем по шагам логику работы такого решения:
ЗаказКлиента, привязывая каждый к соответствующему договору.СвязанныеДокументы или через дополнительный реквизит, указывающий на мастер-заказ.
// Пример алгоритма разделения строк по валютам в кодовой части АРМ
ТаблицаПозиций = Объект.СоставСделки.Выгрузить();
ТаблицаПозиций.Свернуть("Валюта");
Для Каждого СтрВалюта Из ТаблицаПозиций Цикл
НовыйЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
НовыйЗаказ.Дата = ТекущаяДата();
НовыйЗаказ.Партнер = Объект.Клиент;
НовыйЗаказ.Контрагент = Объект.Контрагент;
НовыйЗаказ.Договор = НайтиДоговорПоВалюте(Объект.Контрагент, СтрВалюта.Валюта);
НовыйЗаказ.Валюта = СтрВалюта.Валюта;
ОтборСтрок = Новый Структура("Валюта", СтрВалюта.Валюта);
НайденныеСтроки = Объект.СоставСделки.НайтиСтроки(ОтборСтрок);
Для Каждого СтрокаИсходная Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(НовыйЗаказ.Товары.Добавить(), СтрокаИсходная);
КонецЦикла;
НовыйЗаказ.Записать(РежимЗаписиДокумента.Проведение);
КонецЦикла;
Когда покупатель оплачивает сборный заказ одним рублевым платежным поручением, в типовой системе возникает задача распределения суммы на рублевые и валютные объекты расчетов. Разберем, как распределить платеж без изменения кода системы:
ПоступлениеБезналичныхДенежныхСредств в табличной части «Расшифровка платежа» типовой функционал позволяет разбить одну сумму на несколько строк, указав разные договоры и разные заказы клиентов.ВзаимозачетЗадолженности с операцией переноса аванса клиента. Это гарантирует правильное начисление курсовых разниц в регламентированном учете.Таким образом, архитектурно верным решением задачи мультивалютного заказа является разделение сущностей на уровне интерфейса менеджера с сохранением моновалютности типовых документов ЗаказКлиента. Это исключает риски сбоев при расчете себестоимости, закрытии месяца и формировании первичных документов регламентированного учета.