В процессе разработки систем учета времени (биллинга) в 1С:Документообороте (1С:ДО) часто возникает вопрос о том, как лучше хранить данные о фактически затраченных часах. Разработчики нередко стремятся использовать регистры накопления остаточного типа, чтобы видеть «остаток» неоплаченного или невыставленного клиенту времени. Однако учет времени имеет свою специфику, которая диктует особые правила проектирования метаданных.
В этой статье мы подробно проанализируем типовые механизмы 1С:ДО, разберем разницу между оборотными и остаточными показателями в контексте трудозатрат и выработаем оптимальную схему для реализации учета времени.
Прежде чем приступать к созданию собственных объектов, проанализируем, что уже есть в типовой конфигурации. В 1С:ДО версий 2.1 и 3.0 основным инструментом фиксации времени является Ежедневный отчет. Именно этот документ заменяет собой упомянутые в обсуждении «табельные записи».
При проведении ежедневных отчетов данные попадают в следующие структуры:
ФактическиеТрудозатраты: Это основной регистр, где хранится информация о том, кто, когда, над какой задачей и сколько времени работал. Поскольку это регистр сведений, он позволяет хранить детальную информацию (состояние), но не предназначен для быстрого получения итогов в виде остатков.РабочееВремяПользователей: В типовой конфигурации этот регистр имеет тип Обороты. Проанализируем его назначение: он используется для формирования аналитической отчетности по загрузке персонала и выполнения планов по проектам.Если ваша задача — просто фиксировать время, типовых механизмов 1С:ДО достаточно. Но если требуется реализовать логику «продажи» этих часов клиенту, необходимо проектировать доработки.
Рассмотрим ключевую архитектурную дилемму: какой тип регистра накопления выбрать для учета «неоплаченных» часов. Проанализируем ситуацию на примере сравнения товаров и рабочего времени.
Регистр остатков (например, учет товаров): Представим склад со стульями. Вы закупили 10 стульев (Приход), продали 3 (Расход). В остатке 7. Когда вы продадите оставшиеся 7, ресурс по измерению «Стул» выйдет в ноль. Это классический пример остаточного показателя.
Регистр оборотов (рабочее время): Время — это накапливаемый ресурс. Вы поработали сегодня 2 часа, завтра 3 часа. Итого — 5 часов. Эти часы не «лежат на складе» в физическом смысле. Вы фиксируете факт выполнения работы. Поэтому время по своей природе — это оборотный показатель.
Почему использование регистра остатков для времени может быть ошибкой? Рассмотрим последствия:
Если перед вами стоит задача видеть разницу между «отработанным» и «оплаченным» временем, рассмотрим наиболее надежный способ реализации на базе оборотного регистра накопления.
Проанализируем структуру такого регистра. Мы можем создать один регистр с двумя ресурсами или использовать одно измерение для разделения типов записей.
Вариант с измерением «Вид движения»:
ТрудозатратыКРасчетам.ТипПоказателя (тип: Перечисление.ТипыТрудозатрат со значениями «Факт» и «Оплачено»).КоличествоЧасов.При фиксации работы сотрудником делаем запись с типом «Факт». При выставлении счета клиенту — запись с типом «Оплачено». Чтобы получить «остаток» неоплаченного времени в отчете, мы просто вычисляем разность:
Сумма(КоличествоЧасов) ГДЕ ТипПоказателя = "Факт" - Сумма(КоличествоЧасов) ГДЕ ТипПоказателя = "Оплачено"
Такой подход гарантирует, что система не будет хранить «битые» итоги, а аналитика будет всегда прозрачной. Вы всегда увидите, сколько всего было отработано и сколько всего было закрыто актами.
Если ваша задача — контролировать выполнение бюджета времени по проекту, рассмотрим пример использования оборотного регистра для план-фактного анализа. Выясним причину, по которой это эффективнее остатков:
// Пример логики записи в оборотный регистр
Движение = Движения.ТрудозатратыПроектов.Добавить();
Движение.Период = ДатаОтчета;
Движение.Проект = ТекущийПроект;
Движение.Сотрудник = ТекущийПользователь;
Движение.ВидРабот = Справочники.ВидыРабот.Проектирование;
Движение.КоличествоЧасов = ЧасыРаботы;
// Если это фиксация из плана (например, при утверждении задачи)
Движение.Сценарий = Перечисления.СценарииУчета.План;
// Если это фиксация из ежедневного отчета
Движение.Сценарий = Перечисления.СценарииУчета.Факт;
В этом случае «остаток» времени на выполнение задачи — это не физический остаток в регистре, а расчетная величина в отчете. Это позволяет избежать ситуации, когда при превышении лимита времени (переработке) в регистре остатков появились бы «отрицательные остатки», которые в 1С считаются грубой ошибкой проектирования.
Использование регистра типа Остатки оправдано только в одном случае: если вы реализуете строгий учет взаиморасчетов в часах, аналогичный денежному учету. Например, если клиент вносит предоплату в виде «пакета часов», которые он может расходовать.
В такой модели:
Но даже в этой схеме необходимо предусмотреть механизмы закрытия периодов и списания неиспользованных часов, чтобы таблица остатков не накапливала исторический мусор.
Рассмотрев все аспекты учета времени в 1С:Документообороте, сделаем выводы:
ФактическиеТрудозатраты.РабочееВремяПользователей.