РКО из двух касс
Клиент поставил задачу — при проведении РКО по оплате поставщику добавить возможность оплачивать частями — часть одной, часть из второй кассы.
Я предложил, чтобы сумма РКО не менялась, но происходила авто-инкассация из второй кассы в первую. На том и порешили.
Конечно, в больших организациях это нарушение кассовой дисциплины, но в мелких компаниях удобно.
Добавляем новые реквизиты для кассы и суммы:
С помощью расширения добавляем реквизиты в форму РКО:
Добавляем в конфигурацию подписку на событие:
В подписке пишем код:
Процедура дор_ДопКассаОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт
Если Не ЗначениеЗаполнено(Источник.дор_ДопКасса) ИЛИ Не ЗначениеЗаполнено(Источник.дор_ДопСумма) Тогда
Возврат;
КонецЕсли;
КассаПолучатель = Источник.Касса; //Касса организации
КассаОтправитель = Источник.дор_ДопКасса; //Касса организации или ККМ
ТекСумма = Источник.дор_ДопСумма;
//ОтправительККМ = ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ»);
Если ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ») Тогда
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;
ДвижениеККМПоИсточнику(Источник, ВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
Иначе
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
КонецЕсли;
//=== ДвиженияДенежныхСредств
//Прочитаем текущие движения и запишем потом новые
НЗ = РегистрыНакопления.ДвиженияДенежныхСредств.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
НЗ.Прочитать();
МЗ = НЗ.Добавить();
МЗ.Период = Источник.Дата;
МЗ.ДенежныеСредства = КассаОтправитель;
МЗ.КорДенежныеСредства = КассаПолучатель;
МЗ.ТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
МЗ.КорТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
МЗ.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
МЗ.КорВалюта = Константы.ВалютаРегламентированногоУчета.Получить();
МЗ.Организация = Источник.Организация;
МЗ.Сумма = ТекСумма;
МЗ.СуммаРегл = ТекСумма;
МЗ.СуммаВВалюте = ТекСумма;
МЗ.СуммаВКорВалюте = ТекСумма;
МЗ.ХозяйственнаяОперация = ТекОперация;
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
НЗ.Записать();
КонецПроцедуры
Процедура ДвижениеКассыПоИсточнику(Источник, ТекВидДвижения, ТекКасса, ТекСумма) Экспорт
//=== ДенежныеСредстваНаличные — операция с другой кассой
Если ТекВидДвижения = ВидДвиженияНакопления.Приход Тогда
ТекОперация = Перечисления.ХозяйственныеОперации.ПоступлениеДенежныхСредствИзДругойКассы;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
Иначе
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
КонецЕсли;
НЗ = РегистрыНакопления.ДенежныеСредстваНаличные.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
НЗ.Прочитать();
МЗ = НЗ.Добавить();
МЗ.ВидДвижения = ТекВидДвижения; //ВидДвиженияНакопления.Расход;
МЗ.Период = Источник.Дата;
МЗ.Касса = ТекКасса;
МЗ.Организация = Источник.Организация;
МЗ.Сумма = ТекСумма;
МЗ.СуммаУпр = ТекСумма;
МЗ.СуммаРегл = ТекСумма;
МЗ.ХозяйственнаяОперация = ТекОперация;
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
НЗ.Записать();
КонецПроцедуры
Процедура ДвижениеККМПоИсточнику(Источник, ТекВидДвижения, ТекКасса, ТекСумма) Экспорт
//=== ДенежныеСредстваВКассахККМ — операция с другой кассой
Если ТекВидДвижения = ВидДвиженияНакопления.Приход Тогда
ТекОперация = Перечисления.ХозяйственныеОперации.ВнесениеДенежныхСредствВКассуККМ;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВКассуККМ;
Иначе
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;
КонецЕсли;
НЗ = РегистрыНакопления.ДенежныеСредстваВКассахККМ.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
НЗ.Прочитать();
МЗ = НЗ.Добавить();
МЗ.ВидДвижения = ТекВидДвижения;
МЗ.Период = Источник.Дата;
МЗ.КассаККМ = ТекКасса;
МЗ.Организация = Источник.Организация;
МЗ.Сумма = ТекСумма;
МЗ.СуммаУпр = ТекСумма;
МЗ.СуммаРегл = ТекСумма;
МЗ.ХозяйственнаяОперация = ТекОперация;
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
НЗ.Записать();
КонецПроцедуры
При выборе кассы обнаружил, что немного накосячил, включил в составной тип и бывшую там по-умолчанию тип «Строка»:
Я не совсем уверен насчет того, что правильно прописал статьи и виды операций для регистров, но это не особо критично, клиенту главное, чтобы суммы сходились.
Без дополнительной кассы движения были такие:
Проверяем, формируются ли необходимые движения.
Вынесем в дополнительную кассу (№2) 1000 рублей:
Теперь то же самое, но с кассой ККМ на 1000 рублей:
Время факт: 1,5 час.
UPD: по этой задаче была еще дополнительная доработка.
Клиент попросил сделать выбор дополнительных двух касс:
Я сделал, чтобы выбор был удобнее, т.е. выбирались те кассы, которые еще не выбраны в документе:
&НаКлиенте
Процедура дор_дор_ДопКассаНачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
С = ПолучитьСписокКассДляВыбора();
ДополнительныеПараметры = Новый Структура(«Имя», «дор_ДопКасса»);
ОписаниеОповещения = Новый ОписаниеОповещения(«дор_ДопКассаЗаверешниеВыбора», ЭтаФорма, ДополнительныеПараметры);
ПоказатьВыборИзСписка(ОписаниеОповещения, С, Элемент);
СтандартнаяОбработка = ложь;
КонецПроцедуры
&НаКлиенте
Процедура дор_дор_ДопКасса2НачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
С = ПолучитьСписокКассДляВыбора();
ДополнительныеПараметры = Новый Структура(«Имя», «дор_ДопКасса2»);
ОписаниеОповещения = Новый ОписаниеОповещения(«дор_ДопКассаЗаверешниеВыбора», ЭтаФорма, ДополнительныеПараметры);
ПоказатьВыборИзСписка(ОписаниеОповещения, С, Элемент);
СтандартнаяОбработка = ложь;
КонецПроцедуры
&НаКлиенте
Процедура дор_ДопКассаЗаверешниеВыбора(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
Если ВыбранныйЭлемент <> неопределено Тогда
Объект[ДополнительныеПараметры.Имя] = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьСписокКассДляВыбора() Экспорт
С = Новый СписокЗначений();
З = Новый Запрос(
«ВЫБРАТЬ
| Кассы.Ссылка КАК Ссылка,
| Кассы.Наименование КАК Наименование
|ИЗ
| Справочник.Кассы КАК Кассы
|ГДЕ
| НЕ Кассы.Ссылка В (&ИсключаемыеКассы)
| И НЕ Кассы.ПометкаУдаления
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| КассыККМ.Ссылка,
| КассыККМ.Наименование
|ИЗ
| Справочник.КассыККМ КАК КассыККМ
|ГДЕ
| НЕ КассыККМ.Ссылка В (&ИсключаемыеКассы)
| И НЕ КассыККМ.ПометкаУдаления»);
ИсключаемыеКассы = Новый Массив();
ИсключаемыеКассы.Добавить(Объект.дор_ДопКасса);
ИсключаемыеКассы.Добавить(Объект.дор_ДопКасса2);
ИсключаемыеКассы.Добавить(Объект.Касса);
з.УстановитьПараметр(«ИсключаемыеКассы», ИсключаемыеКассы);
М = З.Выполнить().Выгрузить().ВыгрузитьКолонку(«Ссылка»);
С.ЗагрузитьЗначения(М);
Возврат С;
КонецФункции
Также я сделал контроль правильности заполнения полей документа:
&НаСервере
Процедура дор_ПередЗаписьюНаСервереПеред(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если Объект.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ОплатаПоставщику Тогда
допСуммы = Объект.дор_ДопСумма + Объект.дор_ДопСумма2;
Если допСуммы >= Объект.СуммаДокумента Тогда
Отказ = истина;
Сообщить(«Сумма по кассам: » + допСуммы + » больше или равна сумме документа: » + Объект.СуммаДокумента);
Возврат;
КонецЕсли;
Если Объект.дор_ДопСумма <> 0 и Не ЗначениеЗаполнено(Объект.дор_ДопКасса) Тогда
Отказ = истина;
Сообщить(«Выберите дополнительную кассу 1! «);
Возврат;
КонецЕсли;
Если Объект.дор_ДопСумма2 <> 0 и Не ЗначениеЗаполнено(Объект.дор_ДопКасса2) Тогда
Отказ = истина;
Сообщить(«Выберите дополнительную кассу 2! «);
Возврат;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
И модуль проведения я переписал на две кассы:
Процедура дор_ДопКассаОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт
Если Не ЗначениеЗаполнено(Источник.дор_ДопКасса) ИЛИ
(Не ЗначениеЗаполнено(Источник.дор_ДопСумма) И Не ЗначениеЗаполнено(Источник.дор_ДопСумма2)) Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(Источник.дор_ДопСумма) Тогда
КассаОтправитель = Источник.дор_ДопКасса; //Касса организации или ККМ
дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, Источник.дор_ДопСумма);
КонецЕсли;
Если ЗначениеЗаполнено(Источник.дор_ДопСумма2) Тогда
КассаОтправитель = Источник.дор_ДопКасса2; //Касса организации или ККМ
дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, Источник.дор_ДопСумма2);
КонецЕсли;
КонецПроцедуры
Процедура дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, ТекСумма) Экспорт
КассаПолучатель = Источник.Касса; //Касса организации
//ОтправительККМ = ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ»);
Если ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ») Тогда
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;
ДвижениеККМПоИсточнику(Источник, ВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
Иначе
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
ДвижениеКассыПоИсточнику(Источник, ВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
КонецЕсли;
//=== ДвиженияДенежныхСредств
//Прочитаем текущие движения и запишем потом новые
НЗ = РегистрыНакопления.ДвиженияДенежныхСредств.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
НЗ.Прочитать();
МЗ = НЗ.Добавить();
МЗ.Период = Источник.Дата;
МЗ.ДенежныеСредства = КассаОтправитель;
МЗ.КорДенежныеСредства = КассаПолучатель;
МЗ.ТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
МЗ.КорТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
МЗ.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
МЗ.КорВалюта = Константы.ВалютаРегламентированногоУчета.Получить();
МЗ.Организация = Источник.Организация;
МЗ.Сумма = ТекСумма;
МЗ.СуммаРегл = ТекСумма;
МЗ.СуммаВВалюте = ТекСумма;
МЗ.СуммаВКорВалюте = ТекСумма;
МЗ.ХозяйственнаяОперация = ТекОперация;
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
НЗ.Записать();
КонецПроцедуры
Объем доработки факт: 1 час.
Свежие комментарии