Найти тему
ITsale 1C

Оперативный учёт

Оглавление

Объекты с которыми будем работать и их настройка

Справочник - Номенклатура.

В условии задачи сказано, что могут оказываться как услуги так и товары.
Чтобы отличать какая номенклатура является услугой, а какая товаром создадим у справочника реквизит “ВидНоменклатуры” с типом “ПеречислениеСсылка.ВидыНоменклатуры”. Перечисление “ВидыНоменклатуры” присутствует в каркасной конфигурации изначально.

Документ - ПриходнаяНакладная.

Если при продаже мы можем оказывать и товары и услуги (доставка, ремонт, установка), то при поступлении услуг быть не должно. Например, нельзя оприходовать услугу “ремонт” в количестве 3 штуки.

Для того чтобы в исключить в приходной накладной добавление услуги у реквизита табличной части “Номенклатура” установим параметр выбора:

  • Имя - отбор по реквизиту “ВидНоменклатуры” справочника “Номенклатура”
  • Значение - перечисление “ВидыНоменклатуры” а именно “Товар”
-2

Документ - РасходнаяНакладная

Состав этого документа подходит для решения задачи.
Для обоих документов на закладке “Движения” указываем регистры которые будут формировать движения.

-3
-4

Регистры сведений - УчетнаяПолитика.

Для определения метода списания себестоимости создадим регистр.
Из постановки задачи следует что учетная политика действует год и может быть либо
FIFO либо LIFO.

FIFO (First In, First Out – «Первым пришёл — первым ушёл») и LIFO (Last In, First Out – «последним пришёл — первым ушёл») — методы оценки товарно-материальных ценностей. При учёте запасов однородного товара, купленного в разное время по разной цене, приходится определять: что выдавать первым; и физически (на складе), и на бумаге (в бухгалтерских книгах). По методу FIFO первым выдаётся самый старый из пришедших товаров, по методу LIFO — самый новый.

Поскольку учетная политика действует год, периодичность нашего регистра тоже будет “в пределах года”

-5

Описывать разрезы в которых мы будем хранить метод списания себестоимости нам не нужно, а значит измерения в этом регистре нам не нужны. Нам достаточно одного ресурса с типом “ПеречислениеСсылка.УчетнаяПолитика”.

Перечисление “УчетнаяПолитика” изначально присутствует в каркасной конфигурации.

-6

Регистры накопления - ОстаткиНоменклатуры и Продажи.

Для того чтобы определить какие создавать регистры (а также их измерения и ресурсы) следует посмотреть на отчеты которые даны в задаче.

ОстаткиНоменклатуры

Регистр присутствует в каркасной конфигурации изначально.

На закладке “Прочее” включим у регистра свойство “Разрешить разделение итогов” оно влияет на параллельность работы системы и в каркасной конфигурации по умолчанию выключено.

При создании нового регистра, данное свойство по умолчанию включено.

-7

Посмотрев на отчет, становится понятно, что остатки должны быть в разрезе номенклатуры и партии, а значит измерения будет два:

  • Номенклатура - присутствует в каркасной конфигурации изначально
  • Партия - создаем измерение с типом “ДокументСсылка.ПриходнаяНакладная” поскольку партией является документ “ПриходнаяНакладная”
  • Состав ресурсов также определяется с помощью отчета:Количество - присутствует в каркасной конфигурации изначально
    Стоимость (или Себестоимость) - создаем ресурс с типом число, длина 12, точность 2 (как у реквизита “Сумма” в табличных частях документов “ПриходнаяНакладная” и “РасходнаяНакладная”
Прибыль - будет вычисляться при выводе отчета, поэтому в регистр не добавляем.
-8

Продажи

Данный регистр отсутствует в каркасной конфигурации, его создаем сами. Необходимость этого регистра определяется с помощью отчета который требуется для решения задачи. Поскольку в заголовке отчета написано “Продажи с 01.01.2010 по 31.03.2010” мы с вами выбираем вид регистра “Обороты”.

Для того чтобы определить вид регистра, нужно выбрать один из подходящих ответов:

  • Сколько чего-то накоплено, на какой-то момент времени - значит вид регистра “Остатки”
  • Сколько чего-то накоплено, за какой-то период - значит вид регистра “Обороты”
-9

Наличие ресурсов и измерений мы с вами уже научились определять (подсказкой является отчет).

-10

Перечисления.

Перечисления УчетнаяПолитика и ВидыНоменклатуры в каркасной конфигурации присутствуют изначально и для решения задачи нет никакой необходимости их редактировать.

Отчеты.

По умолчанию отчетов в каркасной конфигурации нет, они создаются вручную. Создадим два отчета ПродажаТоваров и ОстаткиНоменклатуры Для каждого отчета создадим схему компоновки данных и пока на этом закончим.

-11
-12

Проведение документов “Приходная накладная” и “Расходная накладная”.

Приходная накладная

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

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

//Запись текущего набора записей
//Будут очищены предыдущие записи
Движения.ОстаткиНоменклатуры.Записывать = Истина;

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

//Параметр "Ссылка" для выбора конкретного документа
//Параметр "Период" для того, чтобы использовать ЗаполнитьЗначенияСвойств()
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Период", Дата);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

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

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

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

Для проведения этого документа, необходимо сначала определиться с выбором методики проведения. В этом нам поможет блок-схема представленная ниже.

-13

Данных в самом документе нам недостаточно, поэтому использовать будем традиционную методику проведения:

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

//Проверяем указан ли метод списания себестоимости
МетодСписанияСебестоимости = РегистрыСведений.УчетнаяПолитика.ПолучитьПоследнее(Дата).МетодСписания;

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

Движения.ОстаткиНоменклатуры.Записать();
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Движения.Продажи.Записывать = Истина;

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

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


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

Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("МоментВремени", МоментВремени());

РезультатЗапроса = Запрос.Выполнить();

ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

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

Отчеты.

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

Продажа товаров

-14
-15
-16
-17
-18

Остатки номенклатуры

-19

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

Функция НомерНаПечать(Стр) Экспорт
Пока Лев(Стр, 1) = "0" Цикл
Стр = Сред(Стр, 2);
КонецЦикла;
Возврат Стр;
КонецФункции

-20
-21
-22
-23

Ссылка на скачивание dt

-24