Как в 1С:УНФ рассчитать стоимость услуг ответственного хранения в зависимости от количества дней и объема товара?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

Организация услуг ответственного хранения (3PL) или просто сдача складских площадей с тарификацией за объем товара — задача, с которой часто сталкиваются пользователи 1С:Управление нашей фирмой (УНФ). Типовой функционал программы отлично справляется с торговлей и производством, но специализированного биллинга складских услуг (WMS-функционала) в ней "из коробки" нет.

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

Постановка задачи и анализ типовых возможностей

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

  1. Объема товара (м³).
  2. Количества дней хранения.
  3. Тарифа за 1 м³ в сутки (или в месяц).

Многие начинающие пользователи пытаются использовать партионный учет для решения этой задачи. Логика кажется верной: пришла партия, ушла партия, посчитали разницу дат. Однако, как выяснилось в ходе обсуждения, этот метод имеет существенные недостатки для потокового хранения:

Поэтому наиболее правильным подходом является расчет "Кубометро-дней" или "Паллето-дней" на основе остатков товаров.

Алгоритм расчета: Метод ежедневных остатков

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

Разберем математическую модель, предложенную опытными специалистами:

  1. Мы берем остаток товара на начало каждого дня.
  2. Умножаем этот остаток на объем единицы товара.
  3. Суммируем полученные значения за все дни месяца.
  4. Умножаем итоговую сумму (объем × дни) на тариф.

Пример расчета:

Если мы считаем услугу за период с 1 по 15 января, расчет будет выглядеть так:

Итого: 200 + 500 + 180 = 880 единиц объема к оплате. Умножаем на стоимость хранения 1 м³ в день и получаем сумму счета.

Техническая реализация в 1С:УНФ

Поскольку в 1С:УНФ нет документа "Расчет услуг хранения", нам потребуется небольшая доработка или создание внешней обработки (внешнего отчета). Мы не будем снимать конфигурацию с поддержки, а используем механизм расширений или внешних печатных форм/обработок заполнения табличных частей.

Рассмотрим, откуда брать данные. В УНФ основным регистром, хранящим информацию о товарах на складах, является регистр накопления Запасы (или ЗапасыНаСкладах в зависимости от версий и настроек, но чаще мы оперируем общими остатками).

Шаг 1. Подготовка справочника Номенклатура

Чтобы система могла посчитать объем, в карточках номенклатуры должны быть корректно заполнены данные.

Убедимся, что для каждой номенклатуры (или характеристики) заполнен реквизит, отвечающий за объем. В типовой УНФ это может быть реализовано через дополнительные реквизиты или через использование единиц измерения, где прописан коэффициент пересчета в м³.

Шаг 2. Программный алгоритм получения данных

Нам необходимо написать запрос, который получит остатки на каждый день месяца. Получить просто "Остатки на дату" в цикле — не самый производительный метод (хотя для небольших баз рабочий). Более профессиональный подход — использовать виртуальную таблицу ОстаткиИОбороты.

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


// Примерная схема алгоритма для обработки заполнения табличной части
// 1. Определяем период расчета (например, НачалоМесяца и КонецМесяца)
// 2. Получаем остаток на начало периода
// 3. Получаем все обороты за период с детализацией по дням

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

Обратите внимание, что прямой запрос к таблице ОстаткиИОбороты с периодичностью "День" вернет только те дни, когда были движения. А нам нужны все дни, даже если товар просто лежал без движения. Поэтому алгоритм должен быть следующим:

  1. Получаем остаток на начало месяца.
  2. Получаем таблицу оборотов по дням.
  3. В цикле (или запросом с соединением к таблице производственного календаря) проходим по каждому дню месяца.
  4. Если в этот день не было движений, остаток равен остатку предыдущего дня.
  5. Если движения были, пересчитываем текущий остаток.
  6. Накапливаем сумму: СуммаКубов = СуммаКубов + (ТекущийОстатокШт * ОбъемЕдиницы).

Шаг 3. Нюансы учета: День приема и день выдачи

Важный момент, который обсуждался экспертами: как считать неполные дни? Если товар привезли утром, а увезли вечером того же дня — брать ли плату?

Существует несколько стратегий, которые нужно закрепить в договоре с клиентом и реализовать в коде:

Для большинства случаев подходит вариант "Остаток на конец дня" + отдельная услуга за ПРР (Погрузо-разгрузочные работы). ПРР оплачиваются по факту операции (документ Приходная/Расходная накладная), а хранение — за ночевку товара.

Реализация через "Обработку заполнения"

Самый удобный способ для пользователя — создать кнопку "Заполнить расчет хранения" в документе Акт выполненных работ (или Расходная накладная с типом Услуга).

Как это будет работать:

  1. Пользователь создает пустой Акт в конце месяца, выбирает Контрагента и Договор.
  2. Нажимает кнопку "Заполнить -> Рассчитать хранение".
  3. Обработка запрашивает параметры (Период расчета).
  4. Скрипт выполняет запрос к регистру Запасы по данному контрагенту.
  5. Скрипт перебирает дни, суммирует объемы.
  6. В табличную часть документа добавляется строка:
    • Номенклатура: "Услуга ответственного хранения".
    • Количество: Полученное число (например, 880 м³*дней).
    • Цена: Тариф из договора.
    • Сумма: Автоматически рассчитывается.

Это решение позволяет избежать ручных подсчетов в Excel, минимизирует ошибки и сохраняет историю расчетов в 1С (в виде созданных Актов).

Заключение

Для организации биллинга ответственного хранения в 1С:УНФ не обязательно покупать сложную WMS-систему. Достаточно использовать данные регистра накопления Запасы. Ключ к решению — переход от попыток учесть "партии" к математическому расчету интегрального показателя объема товара во времени.

Рекомендуем реализовать этот механизм через Расширение конфигурации, добавив команду заполнения в документы реализации. Это сохранит возможность автоматического обновления 1С:УНФ и решит задачу автоматизации расчетов.

← На главную