← Назад к вопросам
Резервирование товара под клиента
2.3 Middle🔥 171 комментариев
#Конфигурации и типовые
Условие
Доработайте конфигурацию складского учёта — добавьте возможность резервирования товара под клиента.
Требования:
- Документ "РезервированиеТовара" с табличной частью (Номенклатура, Количество)
- Регистр накопления "РезервыТоваров" (измерения: Номенклатура, Контрагент)
- Отчёт "Наличие товаров":
- Общий остаток на складе
- Зарезервированное количество
- Свободный остаток (доступно к продаже)
Контроль
При проведении документа расхода проверять, что количество не превышает свободный остаток.
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Архитектура решения
Решение состоит из трёх компонентов:
- Документ РезервированиеТовара — фиксирует резервирование
- Регистр РезервыТоваров — накапливает информацию о резервах
- Отчёт "Наличие товаров" — показывает доступность
1. Документ "РезервированиеТовара"
Структура
Документ: РезервированиеТовара
├── Реквизиты:
│ ├── Номер (Автонумерация)
│ ├── Дата
│ ├── Контрагент (Ссылка на Справочник.Контрагенты)
│ ├── Склад (Ссылка на Справочник.Склады)
│ └── Статус (Перечисление: Черновик, Активно, Отменено)
│
└── Табличная часть: Товары
├── Номенклатура
├── Количество
└── ЕдиницаИзмерения
Код модуля
Процедура ПередПроведением(Отмена)
// Проверка обязательных реквизитов
Если ПустаяСтрока(Контрагент) Тогда
Отмена = Истина;
Сообщить("Укажите контрагента!");
Возврат;
КонецЕсли;
Если Товары.Количество() = 0 Тогда
Отмена = Истина;
Сообщить("Добавьте товары!");
Возврат;
КонецЕсли;
// Проверка на достаточность свободного товара
Для Каждого СтрокаТовара Из Товары Цикл
ОстатокТовара = ПолучитьОстатокТовара(СтрокаТовара.Номенклатура, Склад);
Зарезервировано = ПолучитьЗарезервированноеКоличество(СтрокаТовара.Номенклатура);
СвободноеКоличество = ОстатокТовара - Зарезервировано;
Если СвободноеКоличество < СтрокаТовара.Количество Тогда
Отмена = Истина;
Сообщить(СтрокаТовара.Номенклатура + ": необходимо " + СтрокаТовара.Количество + " шт, свободно " + СвободноеКоличество + " шт.");
Возврат;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьОстатокТовара(Номенклатура, Склад)
Запрос = Новый Запрос("SELECT SUM(Количество) КАК Остаток FROM ОстаткиТоваров WHERE Номенклатура = &Ном AND Склад = &Склад");
Запрос.УстановитьПараметр("Ном", Номенклатура);
Запрос.УстановитьПараметр("Склад", Склад);
Результат = Запрос.Выполнить();
Возврат Результат.Пусто() ? 0 : Результат.Первая().Остаток;
КонецФункции
Функция ПолучитьЗарезервированноеКоличество(Номенклатура)
Запрос = Новый Запрос("SELECT SUM(Количество) КАК Зарезервировано FROM РезервыТоваров WHERE Номенклатура = &Ном");
Запрос.УстановитьПараметр("Ном", Номенклатура);
Результат = Запрос.Выполнить();
Возврат Результат.Пусто() ? 0 : Результат.Первая().Зарезервировано;
КонецФункции
2. Регистр накопления "РезервыТоваров"
Структура
РегистрНакопления: РезервыТоваров (тип: Остатки)
├── Измерения:
│ ├── Номенклатура
│ ├── Контрагент
│ └── ДокументРезервирования
│
└── Ресурсы:
└── Количество
Правило проведения документа
// При проведении РезервированиеТовара:
Для Каждого СтрокаТовара Из Товары Цикл
Движение = ДвижениеРегистра.РезервыТоваров.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = СтрокаТовара.Номенклатура;
Движение.Контрагент = Контрагент;
Движение.ДокументРезервирования = Ссылка;
Движение.Количество = СтрокаТовара.Количество;
КонецЦикла;
3. Контроль при расходе товара
Модуль документа РасходТоваров
Процедура ПередПроведением(Отмена)
Для Каждого СтрокаТовара Из Товары Цикл
ОстатокТовара = ПолучитьОстатокТовара(СтрокаТовара.Номенклатура, Склад);
Зарезервировано = ПолучитьЗарезервированноеКоличество(СтрокаТовара.Номенклатура);
Свободное = ОстатокТовара - Зарезервировано;
Если ОснованиеРезервирования.Пусто() Тогда
// Обычный расход — проверяем на свободное
Если Свободное < СтрокаТовара.Количество Тогда
Отмена = Истина;
Сообщить("Недостаточно свободного товара");
Возврат;
КонецЕсли;
Иначе
// Расход по резервированию — можем использовать зарезервированное
Если ОстатокТовара < СтрокаТовара.Количество Тогда
Отмена = Истина;
Сообщить("Недостаточно товара");
Возврат;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
4. Отчёт "Наличие товаров"
Процедура ПриКомпоновке(ДокументРезультат, ДанныеПараметров, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТаблицаРезультата = Новая ТаблицаЗначений;
ТаблицаРезультата.Колонки.Добавить("Номенклатура");
ТаблицаРезультата.Колонки.Добавить("Склад");
ТаблицаРезультата.Колонки.Добавить("ОбщийОстаток", Новый ОписаниеТипов("Число"));
ТаблицаРезультата.Колонки.Добавить("Зарезервировано", Новый ОписаниеТипов("Число"));
ТаблицаРезультата.Колонки.Добавить("СвободныйОстаток", Новый ОписаниеТипов("Число"));
Запрос = Новый Запрос("SELECT DISTINCT Номенклатура, Склад, SUM(Количество) КАК Остаток FROM ОстаткиТоваров GROUP BY Номенклатура, Склад");
ДанныеОстатков = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаОстатка Из ДанныеОстатков Цикл
Зарезервировано = ПолучитьЗарезервированное(СтрокаОстатка.Номенклатура);
НоваяСтрока = ТаблицаРезультата.Добавить();
НоваяСтрока.Номенклатура = СтрокаОстатка.Номенклатура.Наименование;
НоваяСтрока.Склад = СтрокаОстатка.Склад.Наименование;
НоваяСтрока.ОбщийОстаток = СтрокаОстатка.Остаток;
НоваяСтрока.Зарезервировано = Зарезервировано;
НоваяСтрока.СвободныйОстаток = СтрокаОстатка.Остаток - Зарезервировано;
КонецЦикла;
РезультатДокумент = Новый ТабличныйДокумент;
РезультатДокумент.Вывести(ТаблицаРезультата);
ДокументРезультат.Вставить(РезультатДокумент);
КонецПроцедуры
Процесс использования
1. Менеджер создаёт РезервированиеТовара
├─ Выбирает контрагента
├─ Добавляет товары
└─ Проводит (система проверяет наличие)
2. Остатки фиксируются в РезервыТоваров
└─ ОбщийОстаток - Зарезервировано = СвободноеКоличество
3. При расходе система проверяет:
├─ Расход по резервированию → используется зарезервированное
└─ Обычный расход → проверяется свободное
4. Отчёт показывает:
├─ Общее количество
├─ Зарезервировано
└─ Свободно к продаже
Это решение предотвращает перепродажу и обеспечивает полный контроль над резервированием.