Финансовая модель. Распределение расходов пропорционально продажам.

Программирование - Практика программирования

Финансовая модель. Распределение административных расходов по подразделениям пропорционально продажам за месяц.

Для кого: для финансового директора - для понимания, что не Excel'ем единым жив финансовый учет.

Для кого: для программиста - для понимания, как внедрить предлагаемую финансовую модель.

Вашему вниманию представлена статья - пошаговое внедрение в УТ 10.3 финансовой модели, при которой  общие административные расходы текущего месяца распределяются по подразделениям пропорционально продажам каждого подразделения за текущий месяц. 

Подобная финансовая модель не реализована типовым функционалом в УТ 10.3, поэтому потребовалась доработка УТ 10.3. Как и любая модель имеет свои допущения и ограничения. Внедрялась на конкретном предприятии с конкретными бизнес-процессами, и поэтому не претендует на универсальность.

Самое скучное

- разобрать структуру решения на уровне таблиц

Шаг 1. Представьте 4 розничных магазина и 1 бэк-офис администрации. Магазины учитываются как подразделения организации (справочник "Подразделения") (см. рисунок).

В УТ 10.3 не так много разрезов учета: справочники Склады, Подразделения, Организации, Проекты, Кассы, Контрагенты, Договора и т.д. - для каждого вида учета (товарный, финансовый) имеется свой набор так называемых измерений, относительно которых накапливаются показатели в соответствующих регистрах накопления.  Для модели был выбран справочник "Подразделения" в качестве разреза учета - достаточно "популярный" разрез учета (см. рисунок).

Шаг 2. Для учета расходов (финансовых) по подразделениям (магазинам) используется регистр накопления "ДвиженияДенежныхСредств". Распределение административных расходов также учитывается проводками по регистру "Движения денежных средств".

Ни один "денежный" регистр накопления не содержит в своем наборе измерений разрез учета "Подразделение", поэтому был расширен тип значений измерения "Проект" на соответствующий справочник. При этом в настройках учета отключен параметр "Вести учет по проектам" - еще раз, учет по проектам не ведется в программе.

Шаг 3. В соответствующих документах "ПлатежноеПоручениеИсходящее", "ПлатежныйОрдерСписаниеДенежныхСредств", "РасходныйКассовыйОрдер" - к имеющемуся типовому полю "Подразделение" была добавлена табличная часть "РаспределениеРасходовПоПодразделениям" с единственным полем "Подразделение" (см. рисунок).

Модель строится на следующем принципе:

- если расход денежных средств относится на конкретное подразделение, то соответствующее подразделение указывается только в типовом поле документа "Подразделение",

- если расход ДС необходимо распределить, то в типовом поле "Подразделение" необходимо выбрать подразделение "Администрация", а в табличной части "РаспределениеРасходовПоПодразделениям" указать все подразделения. Предполагается, что расходы относятся или только к одному подразделению, или сразу ко всем.

Создан флажок "По всем подразделениям", помогающий заполнить подразделения (магазины) в соответствующей
таблице "Распределения расходов по магазинам". При открытии документов выводятся колонки
ПродажиЗаМесяц, РаспределениеРасходов для проверки корректности распределения. Данные показатели
рассчитываются по алгоритмам определения долей распределения расходов (см. рисунок).

Самое сложное

- понять типовые алгоритмы и куда внести изменения с минимальными "потерями"

Шаг 4. В модуле объекта каждого документа проведение доработано следующим образом - в процедуру общего модуля передается массив подразделений:

Процедура ДвиженияПоРегистрамУпр(Режим, Отказ, Заголовок, СтруктураШапкиДокумента)

    ...
      
    УправлениеДенежнымиСредствами.ПровестиСписаниеДенежныхСредствУпр(
       
СтруктураШапкиДокумента, мСтруктураПараметровДенежныхСредств, ТаблицаПлатежейУпр,
       
Движения, Отказ, Заголовок, РаспределениеРасходовПоПодразделениям.ВыгрузитьКолонку("Подразделение")); //доработка+

КонецПроцедуры // ДвиженияПоРегистрамУпр()

 

В соответствующей процедуре общего модуля были внесены следующие правки:

Если Оплачено И (ОтраженоВОперУчете ИЛИ ПоРасчетномуДокументу) Тогда 

        // Проводим по фактическим взаиморасчетам

        // По регистру "Движения денежных средств"

       
ТаблицаДвиженияДенежныхСредств = Движения.ДвиженияДенежныхСредств.ВыгрузитьКолонки();

        ... // здесь код не менялся

        // Недостающие поля.
       
ТаблицаДвиженияДенежныхСредств.ЗаполнитьЗначения(ВидДенежныхСредств, "ВидДенежныхСредств");      

        ... // здесь код не менялся

        //доработка+ начало
       
Если МассивПодразделений <> Неопределено И МассивПодразделений.Количество()>0 Тогда

           
СоответствиеТаблиц = Новый Соответствие;
            Для
кол = 1 По МассивПодразделений.Количество() Цикл

                Если
кол = 1 Тогда

                   
СоответствиеТаблиц.Вставить(МассивПодразделений.Получить(кол-1), ТаблицаДвиженияДенежныхСредств);
                    Продолжить;

                КонецЕсли;

               
СоответствиеТаблиц.Вставить(МассивПодразделений.Получить(кол-1), ТаблицаДвиженияДенежныхСредств.Скопировать());

            КонецЦикла;
          

            ТаблицаДолей = МодульДоработок.ПолучитьТаблицуДолей(Дата, МассивПодразделений);       

           
времТаблицаДвиженияДенежныхСредств = ТаблицаДвиженияДенежныхСредств.СкопироватьКолонки();
            Для Каждого
Эл Из МассивПодразделений Цикл

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

                   
НоваяСтрока = времТаблицаДвиженияДенежныхСредств.Добавить();
                   
ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
                   
НоваяСтрока.Проект      = Эл;
                  

                    //расходы распределяются пропорционально продажам за месяц
                   
СтрокаДолей = ТаблицаДолей.Найти(Эл, "Подразделение");

                   
НоваяСтрока.Сумма       = Стр.Сумма * СтрокаДолей.Доля;
                   
НоваяСтрока.СуммаУпр    = Стр.СуммаУпр * СтрокаДолей.Доля;                

                КонецЦикла;

            КонецЦикла;

           
//что было
            //Движения.ДвиженияДенежныхСредств.мПериод          = ДатаДвижений;
            //Движения.ДвиженияДенежныхСредств.мТаблицаДвижений = ТаблицаДвиженияДенежныхСредств;
            //Движения.ДвиженияДенежныхСредств.ВыполнитьДвижения();

            //что стало
           
Движения.ДвиженияДенежныхСредств.мПериод          = ДатаДвижений;
           
Движения.ДвиженияДенежныхСредств.мТаблицаДвижений = времТаблицаДвиженияДенежныхСредств;
           
Движения.ДвиженияДенежныхСредств.ВыполнитьДвижения();

        Иначе
           
//доработка+
           
ТаблицаДвиженияДенежныхСредств.ЗаполнитьЗначения(Ссылка.Подразделение, "Проект");

           
Движения.ДвиженияДенежныхСредств.мПериод          = ДатаДвижений;
           
Движения.ДвиженияДенежныхСредств.мТаблицаДвижений = ТаблицаДвиженияДенежныхСредств;
           
Движения.ДвиженияДенежныхСредств.ВыполнитьДвижения();

        КонецЕсли;
       
//доработка+ завершена

       ...
// здесь код не менялся

    КонецЕсли;

Самое интересное

- реализовать "соль" решения

Шаг 5. Таблица долей (коэффициентов) получается следующим образом:

Функция ПолучитьТаблицуДолей(ТекДата, СписокПодразделений) Экспорт

    Если Не
ЗначениеЗаполнено(ТекДата) Тогда
       
ТекДата = ТекущаяДата();
    КонецЕсли;

   
ТЗ = Новый ТаблицаЗначений;
   
ТЗ.Колонки.Добавить("Подразделение");
   
ТЗ.Колонки.Добавить("Доля");

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

   
Запрос.УстановитьПараметр("СписокПодразделений", СписокПодразделений);
   
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекДата));
   
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ТекДата));

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

   
К = 1;
   
СуммаДолей = 0;

   
Выборка = Запрос.Выполнить().Выбрать();
    Пока
Выборка.Следующий() Цикл

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

       
Стр = ТЗ.Добавить();
       
Стр.Подразделение = Выборка.Подразделение;
       
Стр.Доля = Доля;

    КонецЦикла;

    Возврат
ТЗ;

КонецФункции

 

В данной модели реализован расчет долей с учетом так называемой "проблемы копеек". Первые три по сумме продаж  магазина (подразделения) получают долю делением ПродажЗаМесяц на ОбщиеПродажиЗаМесяц, четвертый магазин получает долю = 1-СуммаДолей. Реализовано упорядочивание по суммам продаж по подразделениям.

Округления долей производится до 7 знака после запятой - что позволит избежать расхождений при умножении на семизначные суммы расходов.

Самое заключительное

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

Шаг 6. Распределение административных расходов по подразделениям проводится в момент проведения документа. В конце месяца необходимо запустить групповое перепроведение документов. Для этого разработана обработка группового проведения документов - "Перепроведение документов за месяц" - перепроводятся только документы по административным расходам и имеющие заполненную таблицу "Распределение по подразделениям". В групповом перепроведении участвуют только документы вида ПлатежноеПоручениеИсходящее, ПлатежныйОрдерСписаниеДенежныхСредств, РасходныйКассовыйОрдер.

Шаг 7. Отчет по движению денежных средств строится по группировкам "Проект", "Статья движения денежных средств", остальные настройки - опционально при необходимости - "Вид денежных средств" (наличные, безналичные) , "Приход, расход".

Представленный механизм был реализован на платформе 8.3.11.3034 на конфигурации версии УТ 10.3.36.1.

С пользой для клиентов, RustIG (Rustем Iльдарович Gумеров)

См. также

Комментарии
Сортировка: Древо
1. tomvlad 3517 14.05.18 07:28 Сейчас в теме
А что, сейчас уже можно ссылку на свой сайт давать?
2. Rustig 972 15.05.18 11:11 Сейчас в теме
3. tomvlad 3517 15.05.18 11:22 Сейчас в теме
(2) Раньше за такое Доржи бил линейкой по голове обещал строго наказать.
4. Rustig 972 15.05.18 11:56 Сейчас в теме
(3) видимо, это было до внедрения модерации каждой статьи - сейчас модераторы не допускают статьи к публикации, если есть замечания
5. Rustig 972 04.07.18 09:34 Сейчас в теме
(1) оказалось, что нельзя :)
удалил ссылку :(
Оставьте свое сообщение