понедельник, 8 июня 2015 г.

1c специалист решение задачи 1.34

Решение:
Добавим новый справочник "Проекты".
Заведем регистр "Взаиморасчеты".
Расходная накладная будет увеличивать долг контрагентов, приход денег их уменьшать.

1) Расходная накладная

Процедура ОбработкаПроведения(Отказ, Режим)

Движения.Взаиморасчеты.Записывать = Истина;
Движения.Взаиморасчеты.Записать();

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

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
              | -ВзаиморасчетыОстатки.суммаОстаток КАК Аванс
              |ИЗ
              | РегистрНакопления.Взаиморасчеты.Остатки(
              | &ТочкаИтогов,
              | Контрагент = &Контрагент
              | И Проект = ЗНАЧЕНИЕ(Справочник.Проекты.ПустаяСсылка)) КАК ВзаиморасчетыОстатки
              |ГДЕ
              | ВзаиморасчетыОстатки.суммаОстаток < 0";
  
Запрос.УстановитьПараметр("Контрагент",Контрагент);   
Запрос.УстановитьПараметр("ТочкаИтогов",Новый Граница(МоментВремени(),ВидГраницы.Исключая));
Аванс =0;

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

2) Приход денег.


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


Запрос = Новый Запрос;
Запрос.Текст ="ВЫБРАТЬ
             | ПриходДенегТЧ.Проект
             |ПОМЕСТИТЬ ДокТЧ
             |ИЗ
             | Документ.ПриходДенег.ТЧ КАК ПриходДенегТЧ
             |ГДЕ
             | ПриходДенегТЧ.Ссылка = &Ссылка
             |;
             |
             |////////////////////////////////////////////////////////////////////////////////
             |ВЫБРАТЬ
             | ВзаиморасчетыОстатки.Контрагент,
             | ДокТЧ.Проект,
             | ЕСТЬNULL(ВзаиморасчетыОстатки.суммаОстаток, 0) КАК Долг,
             | 1 КАК Приоритет
             |ИЗ
             | ДокТЧ КАК ДокТЧ
             | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Взаиморасчеты.Остатки(
             | &ТочкаИтогов,
             | Контрагент = &Контрагент
             | И Проект В
             | (ВЫБРАТЬ
             | ДокТЧ.Проект
             | ИЗ
             | ДокТЧ)) КАК ВзаиморасчетыОстатки
             | ПО ДокТЧ.Проект = ВзаиморасчетыОстатки.Проект
             |
             |ОБЪЕДИНИТЬ ВСЕ
             |
             |ВЫБРАТЬ
             | ВзаиморасчетыОстатки.Контрагент,
             | ВзаиморасчетыОстатки.Проект,
             | ЕСТЬNULL(ВзаиморасчетыОстатки.суммаОстаток, 0),
             | 2
             |ИЗ
             | РегистрНакопления.Взаиморасчеты.Остатки(
             | &ТочкаИтогов,
             | Контрагент = &Контрагент
             | И НЕ Проект В
             | (ВЫБРАТЬ
             | ДокТЧ.Проект
             | ИЗ
             | ДокТЧ)) КАК ВзаиморасчетыОстатки
             |
             |УПОРЯДОЧИТЬ ПО
             | Приоритет,
             | Долг УБЫВ";

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

Выборка = Запрос.Выполнить().Выбрать();
ОсталосьРаспределить = СуммаОплаты;
Пока Выборка.Следующий() и ОсталосьРаспределить>0 Цикл
Движение = Движения.Взаиморасчеты.ДобавитьРасход();
Движение.Период     = Дата;
Движение.Контрагент = Контрагент;
Движение.Проект     = Выборка.Проект;
КСписанию           = Мин(Выборка.Долг, ОсталосьРаспределить);
Движение.сумма      = КСписанию;
ОсталосьРаспределить = ОсталосьРаспределить - КСписанию;
КонецЦикла;

Если ОсталосьРаспределить >0 Тогда 
Движение = Движения.Взаиморасчеты.ДобавитьРасход();
Движение.Период     = Дата;
Движение.Контрагент = Контрагент;
Движение.сумма      = ОсталосьРаспределить;
КонецЕсли;
КонецПроцедуры


3) Отчет
Отчеты простейшие, единственный момент чтобы незаполненный проект выводился как аванс применим конструкцию:
ВЫБОР
КОГДА ВзаиморасчетыОстатки.Проект = ЗНАЧЕНИЕ(Справочник.Проекты.ПустаяСсылка)
ТОГДА "Аванс"
ИНАЧЕ ВзаиморасчетыОстатки.Проект
КОНЕЦ  

Наверное проще было бы завести предопределенный элемент "Аванс" справочника "Проекты".

Комментариев нет:

Отправить комментарий