Закрытие периода (постановка)
Flake (обсуждение | вклад) (→Расчет сальдо) |
Flake (обсуждение | вклад) (→Статистика по новому механизму) |
||
| Строка 205: | Строка 205: | ||
=== Статистика по новому механизму === | === Статистика по новому механизму === | ||
На примере базы Березы приведем статистику по работе Гедемина с расчетом сальдо. | На примере базы Березы приведем статистику по работе Гедемина с расчетом сальдо. | ||
| + | |||
{| border="1" style="border-collapse:collapse;" | {| border="1" style="border-collapse:collapse;" | ||
!style="background:#ffdead;" |Параметр | !style="background:#ffdead;" |Параметр | ||
Версия 18:33, 22 сентября 2008
Для ускорения работы бухгалтерских отчетов (Журнал-ордер, Анализ счета, Карта счета, Оборотная ведомость, Главная книга) и функций работающих с проводками необходимо реализовать механизм переодического расчета сальдо. Механизм подразумевает выбор проводок за заданный период, их группировка по счетам и соответствующим аналитикам, запись полученного сальдо в новую таблицу. В дальнейшем при построении бухгалтерских отчетов начальное и конечное сальдо должно будет вычисляться на основании данных из этой таблицы.
Содержание |
Расчет сальдо
Механизм расчета
Таблица в которую будет производится запись сгруппированных данных по проводкам будет называться AC_ENTRY_BALANCE. Ее структура будет идентична таблице AC_ENTRY, за исключением некоторых полей:
CREATE TABLE AC_ENTRY_BALANCE ( -------------------------------- -- Эти поля аналогичны AC_ENTRY -------------------------------- ID DINTKEY, COMPANYKEY DINTKEY, ACCOUNTKEY DINTKEY, CURRKEY DINTKEY, DEBITNCU DCURRENCY, DEBITCURR DCURRENCY, DEBITEQ DCURRENCY, CREDITNCU DCURRENCY, CREDITCURR DCURRENCY, CREDITEQ DCURRENCY, --------------------------------- -- Наличие полей аналитических -- признаков зависит от -- конфигурации учета на текущей -- базе данных --------------------------------- USR$GS_CUSTOMER USR$GS_DCUSTOMER, USR$GS_DEPARTMENT USR$GS_DDEPARTMENT, USR$FA_INVCARDKEY USR$FA_INVCARD, USR$GS_GOOD USR$GS_DGOOD, USR$GS_DOCUMENT USR$GS_DDOCUMENT, USR$GS_SERVICE USR$GS_DSERVICE, USR$GS_EMPLOYEE USR$GS_DEMPLOYEE, USR$VATTYPE_KEY USR$VATTYPEKEY, USR$FA_GROUPKEY USR$FA_CIPHERKEY, USR$GS_CONTRACT USR$INV_DCONTRACT, USR$GS_EXPENSES USR$GS_DEXPENSES, USR$GS_ECONOMICACTIVITY USR$DECONOMICACTIVITY, USR$GS_SALETAXRATE DCURRENCY, --------------------------------- -- Следующие поля AC_ENTRY -- не попадут в таблицу итоговых -- значений ---------------------------------ENTRYDATE DDATE,RECORDKEY DMASTERKEY,TRANSACTIONKEY DINTKEY,DOCUMENTKEY DMASTERKEY,MASTERDOCKEY DINTKEY,ACCOUNTPART DACCOUNTPART,DISABLED DBOOLEAN DEFAULT 0,RESERVED DINTEGER,ISSIMPLE DBOOLEAN_NOTNULL NOT NULL);
При изменении структуры таблицы AC_ENTRY, например в случае добавления новой аналитики, структура таблицы AC_ENTRY_BALANCE также будет обновляться.
Сальдо в стандартных отчетах будет считаться исходя из AC_ENTRY_BALANCE + AC_ENTRY. Например, расчет сальдо был сделан на дату CloseDate = 01.01.2008. Мы хотим построить журнал-ордер на дату Date = 01.05.2008. Сальдо на дату Date будет вычислятся как сальдо на дату CloseDate из таблицы AC_ENTRY_BALANCE плюс сальдо за период 01.01.2008 – 01.05.2008 рассчитанное по таблице AC_ENTRY старым методом. То же самое, если нам понадобится сальдо на дату Date = 01.07.2007. Берем сальдо из AC_ENTRY_BALANCE на дату CloseDate и отнимаем сальдо за период 01.07.2007 – 01.01.2008 рассчитанное по таблице AC_ENTRY.
После первого выполнения процедуры расчета сальдо на таблицу AC_ENTRY должен быть повешен универсальный триггер AFTER INSERT OR UPDATE OR DELETE, который будет обновлять данные в таблице AC_ENTRY_BALANCE в соответствии с изменениями в проводках за период предшедствующий расчету. Здесь может возникнуть проблема блокировки, когда с базой работает несколько пользователей и одновременно создается несколько проводок, которые попадают в одну запись таблицы AC_ENTRY_BALANCE. Поэтому было решено отказаться от обновления записей таблицы AC_ENTRY_BALANCE в пользу добавления дельта-записей содержащих величину изменения сальдо по конкретному счету в разрезе соответствующих аналитик.
Например, в AC_ENTRY добавилась проводка:
| Счет | Дебет | Кредит |
|---|---|---|
| 51 | 1500 | 0 |
В таблице AC_ENTRY_BALANCE по 51 счету содержится следующая запись:
| Счет | Дебет | Кредит |
|---|---|---|
| 51 | 25000 | 15000 |
Триггер на таблице AC_ENTRY вставит в таблицу AC_ENTRY_BALANCE дельта-запись, данные примут вид:
| Счет | Дебет | Кредит |
|---|---|---|
| 51 | 25000 | 15000 |
| 51 | 1500 | 0 |
Предварительный текст триггера:
CREATE OR ALTER TRIGGER ac_entry_do_balance FOR ac_entry
ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 15
AS
BEGIN
IF (INSERTING AND NEW.entrydate <= CAST('01.01.2008' AS DATE)
AND (NEW.debitncu > 0) OR (NEW.debitcurr > 0) OR (NEW.creditncu > 0) OR (NEW.creditcurr > 0)) THEN
BEGIN
INSERT INTO AC_ENTRY_BALANCE
(companykey, accountkey, currkey,
debitncu, debitcurr, debiteq,
creditncu, creditcurr, crediteq,
usr$gs_customer, usr$fa_groupkey, usr$gs_department,
usr$fa_invcardkey, usr$gs_good, usr$gs_document)
VALUES
(NEW.companykey,
NEW.accountkey,
NEW.currkey,
NEW.debitncu,
NEW.debitcurr,
NEW.debiteq,
NEW.creditncu,
NEW.creditcurr,
NEW.crediteq,
NEW.usr$gs_customer,
NEW.usr$fa_groupkey,
NEW.usr$gs_department,
NEW.usr$fa_invcardkey,
NEW.usr$gs_good,
NEW.usr$gs_document);
END
ELSE
IF (UPDATING AND OLD.entrydate <= CAST('01.01.2008' AS DATE)
AND (OLD.debitncu <> NEW.debitncu) OR (OLD.creditncu <> NEW.creditncu)
OR (OLD.debitcurr <> NEW.debitcurr) OR (OLD.creditcurr <> NEW.creditcurr)) THEN
BEGIN
INSERT INTO AC_ENTRY_BALANCE
(companykey, accountkey, currkey,
debitncu, debitcurr, debiteq,
creditncu, creditcurr, crediteq,
usr$gs_customer, usr$fa_groupkey, usr$gs_department,
usr$fa_invcardkey, usr$gs_good, usr$gs_document)
VALUES
(OLD.companykey,
OLD.accountkey,
OLD.currkey,
NEW.debitncu-OLD.debitncu,
NEW.debitcurr-OLD.debitcurr,
NEW.debiteq-OLD.debiteq,
NEW.creditncu-OLD.creditncu,
NEW.creditcurr-OLD.creditcurr,
NEW.crediteq-OLD.crediteq,
OLD.usr$gs_customer,
OLD.usr$fa_groupkey,
OLD.usr$gs_department,
OLD.usr$fa_invcardkey,
OLD.usr$gs_good,
OLD.usr$gs_document);
END
ELSE
IF (DELETING AND OLD.entrydate <= CAST('01.01.2008' AS DATE)
AND (OLD.debitncu > 0) OR (OLD.debitcurr > 0) OR (OLD.creditncu > 0) OR (OLD.creditcurr > 0)) THEN
BEGIN
INSERT INTO AC_ENTRY_BALANCE
(companykey, accountkey, currkey,
debitncu, debitcurr, debiteq,
creditncu, creditcurr, crediteq,
usr$gs_customer, usr$fa_groupkey, usr$gs_department,
usr$fa_invcardkey, usr$gs_good, usr$gs_document)
VALUES
(OLD.companykey,
OLD.accountkey,
OLD.currkey,
-OLD.debitncu,
-OLD.debitcurr,
-OLD.debiteq,
-OLD.creditncu,
-OLD.creditcurr,
-OLD.crediteq,
OLD.usr$gs_customer,
OLD.usr$fa_groupkey,
OLD.usr$gs_department,
OLD.usr$fa_invcardkey,
OLD.usr$gs_good,
OLD.usr$gs_document);
END
END
Где CAST('01.01.2008' AS DATE) - дата последнего расчета сальдо. Эту дату можно хранить так же, как хранится дата блокировки периода. То есть хранить в генераторе (например GD_G_ENTRY_BALANCE_DATE) кол-во дней, прошедших с определенной даты (например 17.11.1858) до даты расчета сальдо. Обновлять значение генератора необходимо после каждой процедуры расчета сальдо.
При следующем выполнении процедуры закрытия периода на дату NewCloseDate, данные о проводках до даты CloseDate прошлого закрытия брать из таблицы AC_ENTRY_BALANCE, а данные за промежуток CloseDate - NewCloseDate — из таблицы AC_ENTRY.
Иногда будет необходимо перегруппировать данные в таблице AC_ENTRY_BALANCE путем слияния первоначальной и дельта-записей в одну запись. В момент построения бухгалтерского отчета необходимо проверять количество дельта-записей. Если оно превысит некоторый лимит, то устанавливать флаг, по состоянию которого перестраивать таблицу AC_ENTRY_BALANCE. Это можно делать каждый раз перед/после построения бухгалтерского отчета, или в период простоя Гедемина. Если процедура расчета сальдо будет выполнятся переодически (например, раз в месяц), то данные можно перегруппировать в момент следующего расчета сальдо.
Группировка данных
Перед заполнением таблицы AC_ENTRY_BALANCE данные о проводках необходимо сгруппировать. По умолчанию данные группируются по компании, счету и валюте. Также проводки необходимо группировать по аналитикам. Однако, если группировать данные по всем аналитикам, мы не получим большого уменьшения кол-ва записей, так как многие аналитики не закрываются. Поэтому необходимо дать пользователю выбирать по каким аналитикам необходимо группировать данные при выполнении процедуры расчета сальдо.
Планируется добавить в План счетов дополнительные флажки, по которым и определять необходимость включения данной аналитики в группировку по конкретному счету.
Если при построении бухгалтерского отчета пользователь выберет в группировке аналитику которая не выбрана в Плане счетов, то есть, по которой не рассчитывалось сальдо, то выполнять расчет старым методом (предупредить пользователя?). Можно выделять аналитики по которым было рассчитано сальдо другим цветом.
Статистика по новому механизму
На примере базы Березы приведем статистику по работе Гедемина с расчетом сальдо.
| Параметр | без AC_ENTRY_BALANCE | с AC_ENTRY_BALANCE |
|---|---|---|
| Время построения: | ||
| Карта счета | ||
| Анализ счета | ||
| Журнал-ордер | ||
| Главная книга | ||
| Оборотная ведомость | ||
| Размер базы |