РКО из двух касс

Клиент поставил задачу — при проведении РКО по оплате поставщику добавить возможность оплачивать частями — часть одной, часть из второй кассы.

Я предложил, чтобы сумма РКО не менялась, но происходила авто-инкассация из второй кассы в первую. На том и порешили.

Конечно, в больших организациях это нарушение кассовой дисциплины, но в мелких компаниях удобно.

Добавляем новые реквизиты для кассы и суммы:

С помощью расширения добавляем реквизиты в форму РКО:

Добавляем в конфигурацию подписку на событие:

В подписке пишем код:

Процедура дор_ДопКассаОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт

    Если Не
ЗначениеЗаполнено(Источник.дор_ДопКасса) ИЛИ  Не ЗначениеЗаполнено(Источник.дор_ДопСумма)  Тогда
        Возврат;
    КонецЕсли;


   
КассаПолучатель = Источник.Касса;   //Касса организации
   
КассаОтправитель = Источник.дор_ДопКасса; //Касса организации или ККМ
   
ТекСумма = Источник.дор_ДопСумма;
   
//ОтправительККМ = ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ»);

   
Если ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ») Тогда
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;

       
ДвижениеККМПоИсточнику(ИсточникВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
    Иначе
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;

       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
    КонецЕсли;


   
//===  ДвиженияДенежныхСредств

    //Прочитаем текущие движения и запишем потом новые
   
НЗ = РегистрыНакопления.ДвиженияДенежныхСредств.СоздатьНаборЗаписей();
   
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
   
НЗ.Прочитать();

   
МЗ = НЗ.Добавить();
   
МЗ.Период = Источник.Дата;
   
МЗ.ДенежныеСредства = КассаОтправитель;
   
МЗ.КорДенежныеСредства = КассаПолучатель;
   
МЗ.ТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
   
МЗ.КорТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
   
МЗ.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
   
МЗ.КорВалюта = Константы.ВалютаРегламентированногоУчета.Получить();
   
МЗ.Организация = Источник.Организация;
   
МЗ.Сумма = ТекСумма;
   
МЗ.СуммаРегл = ТекСумма;
   
МЗ.СуммаВВалюте = ТекСумма;
   
МЗ.СуммаВКорВалюте = ТекСумма;
   
МЗ.ХозяйственнаяОперация = ТекОперация;
   
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
   
НЗ.Записать();

КонецПроцедуры


Процедура
ДвижениеКассыПоИсточнику(Источник, ТекВидДвижения, ТекКасса, ТекСумма) Экспорт
   
//===  ДенежныеСредстваНаличные  — операция с другой кассой

   
Если ТекВидДвижения = ВидДвиженияНакопления.Приход Тогда
       
ТекОперация = Перечисления.ХозяйственныеОперации.ПоступлениеДенежныхСредствИзДругойКассы;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
    Иначе
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;
    КонецЕсли;

   
НЗ = РегистрыНакопления.ДенежныеСредстваНаличные.СоздатьНаборЗаписей();
   
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
   
НЗ.Прочитать();

   
МЗ = НЗ.Добавить();
   
МЗ.ВидДвижения = ТекВидДвижения; //ВидДвиженияНакопления.Расход;
   
МЗ.Период = Источник.Дата;
   
МЗ.Касса = ТекКасса;
   
МЗ.Организация = Источник.Организация;
   
МЗ.Сумма = ТекСумма;
   
МЗ.СуммаУпр = ТекСумма;
   
МЗ.СуммаРегл = ТекСумма;
   
МЗ.ХозяйственнаяОперация = ТекОперация;
   
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
   
НЗ.Записать();
КонецПроцедуры

Процедура
ДвижениеККМПоИсточнику(Источник, ТекВидДвижения, ТекКасса, ТекСумма) Экспорт
   
//===  ДенежныеСредстваВКассахККМ — операция с другой кассой
   
Если ТекВидДвижения = ВидДвиженияНакопления.Приход Тогда
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВнесениеДенежныхСредствВКассуККМ;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВКассуККМ;
    Иначе
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;
    КонецЕсли;


   
НЗ = РегистрыНакопления.ДенежныеСредстваВКассахККМ.СоздатьНаборЗаписей();
   
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
   
НЗ.Прочитать();


   
МЗ = НЗ.Добавить();
   
МЗ.ВидДвижения = ТекВидДвижения;
   
МЗ.Период = Источник.Дата;
   
МЗ.КассаККМ = ТекКасса;
   
МЗ.Организация = Источник.Организация;
   
МЗ.Сумма = ТекСумма;
   
МЗ.СуммаУпр = ТекСумма;
   
МЗ.СуммаРегл = ТекСумма;
   
МЗ.ХозяйственнаяОперация = ТекОперация;
   
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
   
НЗ.Записать();
КонецПроцедуры

При выборе кассы обнаружил, что немного накосячил, включил в составной тип и бывшую там по-умолчанию тип «Строка»:

Я не совсем уверен насчет того, что правильно прописал статьи и виды операций для регистров, но это не особо критично, клиенту главное, чтобы суммы сходились.

Без дополнительной кассы движения были такие:

Проверяем, формируются ли необходимые движения.

Вынесем в дополнительную кассу (№2) 1000 рублей:

Теперь то же самое, но с кассой ККМ на 1000 рублей:

Время факт: 1,5 час.

UPD: по этой задаче была еще дополнительная доработка.

Клиент попросил сделать выбор дополнительных двух касс:

Я сделал, чтобы выбор был удобнее, т.е. выбирались те кассы, которые еще не выбраны в документе:

&НаКлиенте
Процедура дор_дор_ДопКассаНачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
   
С = ПолучитьСписокКассДляВыбора();
   
ДополнительныеПараметры = Новый Структура(«Имя», «дор_ДопКасса»);
   
ОписаниеОповещения = Новый ОписаниеОповещения(«дор_ДопКассаЗаверешниеВыбора», ЭтаФорма, ДополнительныеПараметры);
   
ПоказатьВыборИзСписка(ОписаниеОповещения, С, Элемент);
   
СтандартнаяОбработка = ложь;
КонецПроцедуры

&НаКлиенте
Процедура дор_дор_ДопКасса2НачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
   
С = ПолучитьСписокКассДляВыбора();
   
ДополнительныеПараметры = Новый Структура(«Имя», «дор_ДопКасса2»);
   
ОписаниеОповещения = Новый ОписаниеОповещения(«дор_ДопКассаЗаверешниеВыбора», ЭтаФорма, ДополнительныеПараметры);
   
ПоказатьВыборИзСписка(ОписаниеОповещения, С, Элемент);
   
СтандартнаяОбработка = ложь;
КонецПроцедуры

&НаКлиенте
Процедура дор_ДопКассаЗаверешниеВыбора(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    Если
ВыбранныйЭлемент <> неопределено Тогда
       
Объект[ДополнительныеПараметры.Имя] = ВыбранныйЭлемент.Значение;
    КонецЕсли;
КонецПроцедуры


&НаСервере
Функция ПолучитьСписокКассДляВыбора() Экспорт
   
С = Новый СписокЗначений();
   
З = Новый Запрос(
   
«ВЫБРАТЬ
    |   Кассы.Ссылка КАК Ссылка,
    |   Кассы.Наименование КАК Наименование
    |ИЗ
    |   Справочник.Кассы КАК Кассы
    |ГДЕ
    |   НЕ Кассы.Ссылка В (&ИсключаемыеКассы)
    |   И НЕ Кассы.ПометкаУдаления
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    |   КассыККМ.Ссылка,
    |   КассыККМ.Наименование
    |ИЗ
    |   Справочник.КассыККМ КАК КассыККМ
    |ГДЕ
    |   НЕ КассыККМ.Ссылка В (&ИсключаемыеКассы)
    |   И НЕ КассыККМ.ПометкаУдаления»
);
   
ИсключаемыеКассы = Новый Массив();
   
ИсключаемыеКассы.Добавить(Объект.дор_ДопКасса);
   
ИсключаемыеКассы.Добавить(Объект.дор_ДопКасса2);
   
ИсключаемыеКассы.Добавить(Объект.Касса);
   
з.УстановитьПараметр(«ИсключаемыеКассы», ИсключаемыеКассы);
   
М = З.Выполнить().Выгрузить().ВыгрузитьКолонку(«Ссылка»);
   
С.ЗагрузитьЗначения(М);
    Возврат
С;
КонецФункции

Также я сделал контроль правильности заполнения полей документа:

&НаСервере
Процедура дор_ПередЗаписьюНаСервереПеред(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Если
Объект.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ОплатаПоставщику Тогда
       
допСуммы = Объект.дор_ДопСумма + Объект.дор_ДопСумма2;
        Если
допСуммы >= Объект.СуммаДокумента Тогда
           
Отказ = истина;
           
Сообщить(«Сумма по кассам: » + допСуммы + » больше или равна сумме документа: » + Объект.СуммаДокумента);
            Возврат;
        КонецЕсли;

        Если
Объект.дор_ДопСумма <> 0 и Не ЗначениеЗаполнено(Объект.дор_ДопКасса) Тогда
           
Отказ = истина;
           
Сообщить(«Выберите дополнительную кассу 1! «);
            Возврат;
        КонецЕсли;

        Если
Объект.дор_ДопСумма2 <> 0 и Не ЗначениеЗаполнено(Объект.дор_ДопКасса2) Тогда
           
Отказ = истина;
           
Сообщить(«Выберите дополнительную кассу 2! «);
            Возврат;
        КонецЕсли;

    КонецЕсли;
КонецПроцедуры

И модуль проведения я переписал на две кассы:

Процедура дор_ДопКассаОбработкаПроведения(Источник, Отказ, РежимПроведения) Экспорт

    Если Не
ЗначениеЗаполнено(Источник.дор_ДопКасса) ИЛИ
        (Не
ЗначениеЗаполнено(Источник.дор_ДопСумма) И Не ЗначениеЗаполнено(Источник.дор_ДопСумма2))  Тогда
        Возврат;
    КонецЕсли;

    Если
ЗначениеЗаполнено(Источник.дор_ДопСумма) Тогда
       
КассаОтправитель = Источник.дор_ДопКасса; //Касса организации или ККМ
       
дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, Источник.дор_ДопСумма);
    КонецЕсли;

    Если
ЗначениеЗаполнено(Источник.дор_ДопСумма2) Тогда
       
КассаОтправитель = Источник.дор_ДопКасса2; //Касса организации или ККМ
       
дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, Источник.дор_ДопСумма2);
    КонецЕсли;

КонецПроцедуры

Процедура
дор_ВыполнитьДвиженияПоДополнительнойКассе(Источник, КассаОтправитель, ТекСумма) Экспорт
   
КассаПолучатель = Источник.Касса;   //Касса организации
    //ОтправительККМ = ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ»);

   
Если ТипЗнч(КассаОтправитель) = Тип(«СправочникСсылка.КассыККМ») Тогда
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыемкаДенежныхСредствИзКассыККМ;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ПоступлениеДенежныхСредствИзКассыККМ;

       
ДвижениеККМПоИсточнику(ИсточникВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
    Иначе
       
ТекОперация = Перечисления.ХозяйственныеОперации.ВыдачаДенежныхСредствВДругуюКассу;
       
ТекСтатья = Справочники.СтатьиДвиженияДенежныхСредств.ВыдачаДенежныхСредствВДругуюКассу;

       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Расход, КассаОтправитель, ТекСумма);
       
ДвижениеКассыПоИсточнику(ИсточникВидДвиженияНакопления.Приход, КассаПолучатель, ТекСумма);
    КонецЕсли;


   
//===  ДвиженияДенежныхСредств

    //Прочитаем текущие движения и запишем потом новые
   
НЗ = РегистрыНакопления.ДвиженияДенежныхСредств.СоздатьНаборЗаписей();
   
НЗ.Отбор.Регистратор.Установить(Источник.Ссылка);
   
НЗ.Прочитать();

   
МЗ = НЗ.Добавить();
   
МЗ.Период = Источник.Дата;
   
МЗ.ДенежныеСредства = КассаОтправитель;
   
МЗ.КорДенежныеСредства = КассаПолучатель;
   
МЗ.ТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
   
МЗ.КорТипДенежныхСредств = Перечисления.ТипыДенежныхСредств.Наличные;
   
МЗ.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
   
МЗ.КорВалюта = Константы.ВалютаРегламентированногоУчета.Получить();
   
МЗ.Организация = Источник.Организация;
   
МЗ.Сумма = ТекСумма;
   
МЗ.СуммаРегл = ТекСумма;
   
МЗ.СуммаВВалюте = ТекСумма;
   
МЗ.СуммаВКорВалюте = ТекСумма;
   
МЗ.ХозяйственнаяОперация = ТекОперация;
   
МЗ.СтатьяДвиженияДенежныхСредств = ТекСтатья;
   
НЗ.Записать();
КонецПроцедуры

Объем доработки факт: 1 час.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *