комментария 3 на “Базовый курс. Занятие №8”

  1. Жанна Литвина 18.04.2016 в 15:21

    1. Создала спр. “Менеджеры”, подчиненный спр. “Контрагенты”
    для сохранения контактов с контрагентами.

    Модуль объекта документа “Контакты”

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

        Запрос.УстановитьПараметр("Владелец",Контрагент );
        Запрос.УстановитьПараметр("Менеджер",Менеджер );
         
        Результат = Запрос.Выполнить();
        Если Результат.Пустой() Тогда
            НовыйМенеджер=Справочники.Менеджеры.СоздатьЭлемент();
            НовыйМенеджер.Владелец=Контрагент;
            НовыйМенеджер.Менеджер=Менеджер;
            НовыйМенеджер.Записать();     
        КонецЕсли;

    Форма документа “Контакты”

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        ДокОбъект=РеквизитФормыВЗначение("Объект");
        ДокОбъект.Менеджер=ОбщиеФункцииСервер.СинхронизацияПользователей();
        ЗначениеВРеквизитФормы(ДокОбъект,"Объект");
    КонецПроцедуры

    Для выбора контактных лиц, указанного контрагента, реквизит документа “Контактное лицо” связан с реквизитом “Контрагент”

    2. Для хранения различных прайс-листов создала спр. “ТипыЦенаНоменклатуры”, ссылка на него присутствует во всех документах по закупкам и продажам.
    Для хранения цен на товары по разным прайс-листам создала регистр сведений “ЦеныНоменклатуры” с измерениями: “Номенклатура”, “Тип цены” = Ссылка на спр.”ТипыЦенаНоменклатуры”; ресурс: “Цена”.
    Записи в регистр будут добавляться при проведении документов “Закупка” и “Реализация”

    3. Для хранения остатков товаров создала регистр остатков “Остатки товаров”. Измерения: “Номенклатура”, “Качество”, Ресурсы: “Количество”. Регистраторы: “Закупки”, “Авансовый отчет”, “Реализация”

    4. Для хранения данных о закупках от поставщиков создала оборотный регистр “Закупки”. Измерения: “Поставщик”,”Номенклатура”, Ресурсы: “Количество”, “Сумма”. Регистраторы: “Закупки”, “Авансовый отчет”.

    5. Создала журнал документов “Документы закупки”. В графе “Контрагент” указала реквизит “Поставщик” документов “Закупки” и “Авансовый отчет”. Для графы “Сумма” в документах создала реквизиты “Сумма документа”, которые заполняю в процедуре “ПередЗаписью” модуля объекта.

    6. Для запрета изменения базовой единицы измерения номенклатуры, использую процедуру “ОбработкаПроверкиЗаполнения” модуля объекта спр. “Номенклатура”. Если было движение в оборотном регистре “Закупки” и базовая единица отличается от новой, то запись запрещена.

    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
       
        Если ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Услуга Тогда
       
            Индекс = ПроверяемыеРеквизиты.Найти("БазоваяЕдиница");
            Если Индекс <> Неопределено Тогда       
                ПроверяемыеРеквизиты.Удалить(Индекс);     
            КонецЕсли;
        ИначеЕсли ЭтоНовый()=Ложь Тогда
            Индекс = ПроверяемыеРеквизиты.Найти("БазоваяЕдиница");
            ЗначениеБазовойЕдиницы=ПроверяемыеРеквизиты.Получить(Индекс);  
               
            ДвижениеНоменклатуры=РегистрыНакопления.Закупки;
            Фильтр=Новый Структура();
            Фильтр.Вставить("Номенклатура",ЭтотОбъект.Ссылка);
            ТабОборотов=ДвижениеНоменклатуры.Обороты(,,Фильтр,"Номенклатура");
            Если ТабОборотов.Количество()>0 Тогда
                НоменклатураСтроки= ТабОборотов.Получить(0).Номенклатура;
               
                Если НоменклатураСтроки.БазоваяЕдиница<>ЗначениеБазовойЕдиницы Тогда
                    // запрещено менять значение базовой единицы, если по нему было движение
                    Сообщить("Запрещено менять значение базовой единицы!");
                    Отказ=Истина;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
       
    КонецПроцедуры

    7. Для подстановки цены при выборе номенклатуры, согласно указанного прайса использую данные из регистра сведений “Цены номенклатуры”.
    События формы документов по закупке и реализации:
    Для реквизита “Номенклатура” ОбработкаВыбора-ТоварыНоменклатураОбработкаВыбора()

    Для реквизитов “Цена” и “Количество” ПриИзменении – РасчетСуммы()
    Для реквизита “Сумма” ПриИзменении – ТоварыСуммаПриИзменении()

    &НаКлиенте
    Процедура ТоварыНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
            Элементы.Товары.ТекущиеДанные.ЕдиницаИзмерения=ОбщиеФункцииСервер.ПолучитьБазовуюЕИ(ВыбранноеЗначение);  
        Элементы.Товары.ТекущиеДанные.Цена=ОбщиеФункцииСервер.ПолучитьЦену(ВыбранноеЗначение, Объект.Дата, Объект.Прайс);
    КонецПроцедуры


    &НаКлиенте
    Процедура ТоварыСуммаПриИзменении(Элемент)
        ПорядокПересчетаСуммы=ПолучитьКонстантуНаСервере();
        Если ПорядокПересчетаСуммы=1 Тогда
             Элементы.Товары.ТекущиеДанные.Количество=Окр(Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Цена,3,1);
        Иначе 
             Элементы.Товары.ТекущиеДанные.Цена=Окр(Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Количество,2,1);
        КонецЕсли;
    КонецПроцедуры  

    &НаСервереБезКонтекста
    Функция ПолучитьКонстантуНаСервере()
        Возврат Константы.ПересчетПриИзмененииСуммы.Получить();
    КонецФункции // ПолучитьКонстантуНаСервере()

    &НаКлиенте
    Процедура РасчетСуммы(Элемент)
        Элементы.Товары.ТекущиеДанные.Сумма=Окр(Элементы.Товары.ТекущиеДанные.Количество*Элементы.Товары.ТекущиеДанные.Цена,2,1);
    КонецПроцедуры

    Общий модуль.ОбщиеФункцииСервер

    Функция ПолучитьЦену(Ссылка, Дата, Прайс) Экспорт
       
        Отбор = Новый Структура("Номенклатура,ТипЦены");
        Отбор.Вставить("Номенклатура",Ссылка);
        Отбор.Вставить("ТипЦены",Прайс);
        Возврат РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(Дата,Отбор).Цена;
       
    КонецФункции

    Модуль объекта документа “Закупки”

    Процедура ОбработкаПроведения(Отказ, РежимПроведения)
        Движения.ОстаткиТоваров.Записывать=Истина;
        Движения.Закупки.Записывать=Истина;

        Для каждого СтрокаТовары Из Товары Цикл
            // определим цену
            ТекКоличество=0;
            Если СтрокаТовары.ЕдиницаИзмерения<>СтрокаТовары.Номенклатура.БазоваяЕдиница Тогда
                 
                 Выборка=Справочники.ЕдиницыИзмеренияНоменклатуры.Выбрать(,СтрокаТовары.Номенклатура);              
                 Пока Выборка.Следующий() Цикл
                    СтрокаВыборки = Выборка.ПолучитьОбъект();

                    Если СтрокаВыборки.ЕдиницаПоКлассификатору=СтрокаТовары.ЕдиницаИзмерения Тогда
                         ТекКоличество=СтрокаТовары.Количество*СтрокаВыборки.К;
                         Прервать;
                    КонецЕсли;
                 КонецЦикла;
                 Если ТекКоличество=0 Тогда
                    Сообщить("Не установлен коэффициент для пересчета единицы измерения");
                    Отказ=Истина;
                    Прервать;
                 КонецЕсли;
            Иначе
                ТекКоличество=СтрокаТовары.Количество;
            КонецЕсли;
           
            Менеджер=РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
            Менеджер.Период=Дата;
            Менеджер.ТипЦены=Прайс;
            Менеджер.Номенклатура=СтрокаТовары.Номенклатура;
            Менеджер.Цена=Окр(СтрокаТовары.Сумма/ТекКоличество,2,1);
            Менеджер.Записать();  
            //
            Если СтрокаТовары.Номенклатура.ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Товар Тогда
                Движение=Движения.ОстаткиТоваров.ДобавитьПриход();
                Движение.Период=Дата;
                Движение.Номенклатура=СтрокаТовары.Номенклатура;
                Движение.Качество=СтрокаТовары.Брак;
                Движение.Количество=ТекКоличество;  
                //
                Движение=Движения.Закупки.Добавить();
                Движение.Период=Дата;
                Движение.Номенклатура=СтрокаТовары.Номенклатура;
                Движение.Поставщик=Поставщик;
                Движение.Количество=ТекКоличество;  
                Движение.Сумма=СтрокаТовары.Сумма;  
            КонецЕсли;
        КонецЦикла;  
       
    КонецПроцедуры

    Модуль объекта документа “Реализация”

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

                    Если СтрокаВыборки.ЕдиницаПоКлассификатору=СтрокаТовары.ЕдиницаИзмерения Тогда
                         ТекКоличество=СтрокаТовары.Количество*СтрокаВыборки.К;
                         Прервать;
                    КонецЕсли;
                 КонецЦикла;
                 Если ТекКоличество=0 Тогда
                    Сообщить("Не установлен коэффициент для пересчета единицы измерения");
                    Отказ=Истина;
                    Прервать;
                 КонецЕсли;
            Иначе
                ТекКоличество=СтрокаТовары.Количество;
            КонецЕсли;
           
            Менеджер=РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
            Менеджер.Период=Дата;
            Менеджер.ТипЦены=Прайс;
            Менеджер.Номенклатура=СтрокаТовары.Номенклатура;
            Менеджер.Цена=Окр(СтрокаТовары.Сумма/ТекКоличество,2,1);
            Менеджер.Записать();  
            //
            Если СтрокаТовары.Номенклатура.ВидНоменклатуры=Перечисления.ВидыНоменклатуры.Товар Тогда
                Движение=Движения.ОстаткиТоваров.ДобавитьРасход();
                Движение.Период=Дата;
                Движение.Номенклатура=СтрокаТовары.Номенклатура;
                Движение.Качество=СтрокаТовары.Брак;
                Движение.Количество=ТекКоличество;  
            КонецЕсли;
        КонецЦикла;  
       
    КонецПроцедуры

    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
        ПроверяемыеРеквизиты.Удалить(ПроверяемыеРеквизиты.Найти("Товары.Количество"));
       
        // Обходим строки и проверяем заполнение реквизита
        Для Индекс = 0 по Товары.Количество()-1 Цикл
            СтрокаТовар = Товары.Получить(Индекс);
            Если Не ЗначениеЗаполнено(СтрокаТовар.Количество) Тогда
                Сообщение = Новый СообщениеПользователю();
                Сообщение.Текст = "В строке " + (Индекс+1) + " не заполнено количество номенклатуры";
                Сообщение.Поле = "Товары[" + Индекс + "].Количество";
                Сообщение.УстановитьДанные(ЭтотОбъект);
                Сообщение.Сообщить();
                Отказ = Истина;
            Иначе
                Отбор=Новый Структура();
                Отбор.Вставить("Номенклатура", СтрокаТовар.Номенклатура);
                Отбор.Вставить("Качество", СтрокаТовар.Брак);
                Таблица=РегистрыНакопления.ОстаткиТоваров.Остатки(ЭтотОбъект.МоментВремени(),Отбор);
                ДоступноеКоличество=Таблица.Итог("Количество");
                Если ДоступноеКоличество<СтрокаТовар.Количество Тогда
                     Сообщение = Новый СообщениеПользователю();
                     Сообщение.Текст = "В строке " + (Индекс+1) + " количество номенклатуры превышает допустимое значение = "+ДоступноеКоличество;
                     Сообщение.Поле = "Товары[" + Индекс + "].Количество";
                     Сообщение.УстановитьДанные(ЭтотОбъект);
                     Сообщение.Сообщить();
                     Отказ = Истина;        
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;

    КонецПроцедуры
  2. Aleksandr.nett 10.02.2016 в 00:23

    Домашнее задание № 8 Блок 2.
    Привязку менеджеров реализуем – для справочника «Пользователи» (Менеджеры) в качестве владельца укажем справочник «Контрагенты»
    В документе КонтактСКлиентом добавим реквизит Менеджер –тип Справочник Пользователи
    Алгоритм заполнения и проведения в модуле объекта:
    <

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

    Процедура ОбработкаПроведения(Отказ, РежимПроведения)
        ОпределитьИсториюКонтактовСКонтрагентом(Менеджер);      
    КонецПроцедуры

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

    // Хранение цен на товары будем регистрировать с помощью документа ПрайсЛист
    Создадим у него табличную часть «Товары» с реквизитами:
    Номенклатура – СправочникСсылка.Номенклатура
    Цена – Число
    ВидЦены – СправочникСсылка.ЦеныНоменклатуры
    ЕдиницаИзмерения – СправочникСсылка.ЕдиницыИзмеренияНоменклатуры, СправочникСсылка.КлассификаторЕдиницИзмерения (составной тип)

    Для документа Поступление товаров алгоритм заполнения и проведения реализуем в модуле объекта :
    <

    Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
       
        Если ЭтотОбъект.ЭтоНовый() Тогда
           
            Контрагент = ДанныеЗаполнения;   
           
            Товары.Загрузить(ОбщиеНастройкиСервер.ПолучитьДанныеПоследнегоДокумента(Ссылка,Контрагент));
        КонецЕсли;
       
       
    КонецПроцедуры


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

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

        // регистр ЗакупкиПоставщиков
        Движения.ЗакупкиПоставщиков.Записывать = Истина;
        Для Каждого ТекСтрокаТовары Из Товары Цикл
            Движение = Движения.ЗакупкиПоставщиков.Добавить();
            Движение.Период = Дата;
            Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
            Движение.Контрагент = Контрагент;
            Движение.Количество = ТекСтрокаТовары.Количество;
            Движение.Стоимость = ТекСтрокаТовары.Сумма;
        КонецЦикла;


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

    Для документа Поступление товаров алгоритм заполнения в модуле Формы элемента
    <

    &НаКлиенте
    Процедура ТоварыНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
       
        Элементы.Товары.ТекущиеДанные.ЕдиницаИзмерения =  ПолучитьБазовуюЕдиницуИзмерения(ВыбранноеЗначение);
        Товар = Элементы.Товары.ТекущиеДанные.Номенклатура;
        Элементы.Товары.ТекущиеДанные.Цена = ПолучитьЦенуНоменклатурыПоПрайсЛисту(Объект.ПрайсЛист,ВыбранноеЗначение);
        Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;  
        Элементы.Товары.ТекущиеДанные.Качество =  ПолучитьКачествоТовараПоУмолчанию();
       
    КонецПроцедуры


    &НаСервереБезКонтекста
    Функция ПолучитьБазовуюЕдиницуИзмерения(ВыбранноеЗначение)

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

    &НаСервереБезКонтекста
    Функция ПолучитьЦенуНоменклатурыПоПрайсЛисту(Ссылка,Товар)

           
        Запрос = Новый Запрос;
        Запрос.Текст =
            "ВЫБРАТЬ
            |   ПрайсЛистТовары.Цена
            |ИЗ
            |   Документ.ПрайсЛист.Товары КАК ПрайсЛистТовары
            |ГДЕ
            |   ПрайсЛистТовары.Номенклатура = &Номенклатура
            |   И ПрайсЛистТовары.Ссылка = &Ссылка";
       
        Запрос.УстановитьПараметр("Номенклатура", Товар);
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
       
        РезультатЗапроса = Запрос.Выполнить();
       
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
       
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            Возврат  ВыборкаДетальныеЗаписи.Цена;
        КонецЦикла;
       


    КонецФункции // ПолучитьЦенуНоменклатурыПоПрайсЛисту()


    &НаКлиенте
    Процедура ТоварыЦенаПриИзменении(Элемент)
       
        Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;
       
    КонецПроцедуры


    &НаКлиенте
    Процедура ТоварыКоличествоПриИзменении(Элемент)
       
        Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;
       
    КонецПроцедуры


    &НаКлиенте
    Процедура ТоварыСуммаПриИзменении(Элемент)
         // прересчет с помощью константы ?
        Элементы.Товары.ТекущиеДанные.Цена          =  Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Количество;
        Элементы.Товары.ТекущиеДанные.Количество =  Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Цена;
       
    КонецПроцедуры

    &НаСервереБезКонтекста
    Функция ПолучитьКачествоТовараПоУмолчанию()

    Возврат Справочники.СтепениБракаТоваров.Новый;   

    КонецФункции // ПолучитьКачествоТовараПоУмолчанию()

    &НаСервере
    Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
       
    ТекущийОбъект.СуммаИтого =   Объект.Товары.Итог("Сумма");
    КонецПроцедуры

    <

    Для документа Реализация товаров алгоритм заполнения и проведения реализуем в модуле объекта
    <

    Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
       
       
        Если ЭтотОбъект.ЭтоНовый() Тогда
           
            Контрагент = ДанныеЗаполнения;   
           
            Товары.Загрузить(ОбщиеНастройкиСервер.ПолучитьДанныеПоследнегоДокумента(Ссылка,Контрагент));
           
        КонецЕсли;
       
       
    КонецПроцедуры

    Функция ПолучитьДанныеПоследнегоДокумента(Контрагент)

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


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

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

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

    Для документа Реализация товаров алгоритм заполнения в модуле Формы элемента
    <

    &НаКлиенте
    Процедура ТоварыНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
       
          Элементы.Товары.ТекущиеДанные.ЕдиницаИзмерения =  ПолучитьБазовуюЕдиницуИзмерения(ВыбранноеЗначение);
          Товар = Элементы.Товары.ТекущиеДанные.Номенклатура;
          Элементы.Товары.ТекущиеДанные.Цена = ПолучитьЦенуНоменклатурыПоПрайсЛисту(Объект.ПрайсЛист,ВыбранноеЗначение);
          Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;
          Элементы.Товары.ТекущиеДанные.Качество =  ПолучитьКачествоТовараПоУмолчанию();
    КонецПроцедуры


    &НаСервереБезКонтекста
    Функция ПолучитьБазовуюЕдиницуИзмерения(ВыбранноеЗначение)

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

    &НаСервереБезКонтекста
    Функция ПолучитьЦенуНоменклатурыПоПрайсЛисту(Ссылка,Товар)

           
        Запрос = Новый Запрос;
        Запрос.Текст =
            "ВЫБРАТЬ
            |   ПрайсЛистТовары.Цена
            |ИЗ
            |   Документ.ПрайсЛист.Товары КАК ПрайсЛистТовары
            |ГДЕ
            |   ПрайсЛистТовары.Номенклатура = &Номенклатура
            |   И ПрайсЛистТовары.Ссылка = &Ссылка";
       
        Запрос.УстановитьПараметр("Номенклатура", Товар);
        Запрос.УстановитьПараметр("Ссылка", Ссылка);
       
        РезультатЗапроса = Запрос.Выполнить();
       
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
       
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            Возврат  ВыборкаДетальныеЗаписи.Цена;
        КонецЦикла;
       


    КонецФункции // ПолучитьЦенуНоменклатурыПоПрайсЛисту()


    &НаКлиенте
    Процедура ТоварыЦенаПриИзменении(Элемент)
       
        Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;
       
    КонецПроцедуры


    &НаКлиенте
    Процедура ТоварыКоличествоПриИзменении(Элемент)
       
        Элементы.Товары.ТекущиеДанные.Сумма = Элементы.Товары.ТекущиеДанные.Цена*Элементы.Товары.ТекущиеДанные.Количество;
       
    КонецПроцедуры


    &НаКлиенте
    Процедура ТоварыСуммаПриИзменении(Элемент)
         // прересчет с помощью константы ?
        Элементы.Товары.ТекущиеДанные.Цена          =  Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Количество;
        Элементы.Товары.ТекущиеДанные.Количество =  Элементы.Товары.ТекущиеДанные.Сумма/Элементы.Товары.ТекущиеДанные.Цена;
       
    КонецПроцедуры

    &НаСервереБезКонтекста
    Функция ПолучитьКачествоТовараПоУмолчанию()

    Возврат Справочники.СтепениБракаТоваров.Новый;   

    КонецФункции // ПолучитьКачествоТовараПоУмолчанию()
    <

    Создадим Регистры накопления :
    ОстаткиТоваров – вид Остатки
    Измерения:
    Номенклатура – СправочникСсылка.Номенклатура
    Качество – СправочникСсылка.СтепениБракаТоваров
    ЕдиницаИзмерения – СправочникСсылка.КлассификаторЕдиницИзмерения
    Ресурс – Количество
    ЗакупкиПоставщиков – вид Обороты
    Измерения:
    Номенклатура – СправочникСсылка.Номенклатура
    Контрагент – СправочникСсылка. Контрагент
    Ресурсы – Количество, Стоимость

    Реализуем проверку запрета изменения Базовой единицы измерения для справочника Номенклатура
    В модуле объекта :
    <

    Процедура ПередЗаписью(Отказ)
       
        Если ЗначениеЗаполнено(Ссылка)   Тогда

        Если НЕ ПроверитьНаличиеДвиженийПоНоменклатуре(Ссылка) Тогда
           
            Отказ = Истина;
           
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "Изменение номенклатуры:"+Наименование+" запрещено! Имеются записи в регистрах!";
            Сообщение.Сообщить();

            КонецЕсли;

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


    Функция ПроверитьНаличиеДвиженийПоНоменклатуре(Ссылка) Экспорт

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


    КонецФункции // ПроверитьНаличиеДвиженийПоНоменклатуре()
    <

    Проверку запрета изменения Базовой единицы измерения в модуле формы:
    <

    &НаКлиенте
    Процедура БазоваяЕдиницаИзмеренияПриИзменении(Элемент)
       
        Перем Результат;
       
        Документ = Объект;
    Если ЗначениеЗаполнено(Документ.Ссылка)   Тогда

        БазоваяЕдиницаИзмеренияПриИзмененииНаСервере(Документ,Результат);
       
        Если НЕ Результат  Тогда
                Предупреждение("Изменение номенклатуры:"+Объект.Наименование+" запрещено! Имеются записи в регистрах!");
            КонецЕсли;
       

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

    &НаСервере
    Процедура БазоваяЕдиницаИзмеренияПриИзмененииНаСервере(Документ,Результат)

        СпрОбъект = РеквизитФормыВЗначение("Объект");
        Результат = СпрОбъект.ПроверитьНаличиеДвиженийПоНоменклатуре(Документ.Ссылка);
       
       
    КонецПроцедуры // БазоваяЕдиницаИзмеренияПриИзменении()
    <

    Создадим журнал документов «Поступления товаром»
    , включим в него документ «ПоступлениеТоваров», добавим Графы – Контрагент Сумма документа, добавим форму списка , настроим на ней расположение элементов Вид документа, Контрагент, Сумма документа.

  3. добавляем реквизиты “Менеджер”
    в обработке проведения документа “КонтактыМенеджеров”:

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

    добавляем справочник “ТипыЦен”
    добавляем независимый периодический рег.св. “ЦеныНоменклатуры”
    – ТипЦен
    – Номенклатура
    – Цена
    Реквизит “ТипЦен” добавим в документы

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

    добавим константу “Пересчет цены при изменении суммы”

    Процедура СуммаПриИзменении(ТД) Экспорт
        Если Константы.ПересчетЦеныПриИзмененииСуммы.Получить() Тогда
            ТД.Цена = ?(ТД.Количество=0, 0, ТД.Сумма / ТД.Количество);
        Иначе
            ТД.Количество = ?(ТД.Цена=0, 0, ТД.Сумма / ТД.Цена);
        КонецЕсли;
    КонецПроцедуры

    перенесем итоги по сумме на форму
    Добавляю рег.накопления ТоварыНаСкладах (остатки):
    – Номенклатура
    – Качество
    – Количество
    Добавляю рег.накопления Закупки (обороты)
    – Контрагент
    – Номенклатура
    – Количество
    – Стоимость
    В обработке проведения док. Поступления:

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

    запрещать изменять базовую единицу
    измерения для номенклатуры:

    Процедура ПередЗаписью(Отказ)
        Если НЕ ЭтоНовый() Тогда
            Если БазоваяЕдиницаИзмерения <> Ссылка.БазоваяЕдиницаИзмерения Тогда
                Запрос = Новый Запрос;
                Запрос.Текст =
                "ВЫБРАТЬ
                |   ТоварыНаСкладахОбороты.Номенклатура
                |ИЗ
                |   РегистрНакопления.ТоварыНаСкладах.Обороты(, , , Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОбороты";
                Запрос.УстановитьПараметр("Номенклатура", Ссылка);
                Если НЕ Запрос.Выполнить().Пустой() Тогда
                    Отказ = Истина;
                    Сообщить("БазоваяЕдиницаИзмерения изменять нельзя!");
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры

    в документ поступления добавим реквизит СуммаДокумента
    и тогда в журнале документов, можно будет добавить графу “СуммаДокумента”