Закрытие периода (постановка)
Для ускорения работы бухгалтерских отчетов (Журнал-ордер, Анализ счета, Карта счета, Оборотная ведомость, Главная книга) и функций работающих с проводками необходимо реализовать механизм закрытия периода. Бухгалтерское закрытие периода подразумевает выбор проводок за заданный период, их группировка по счетам и соответствующим аналитикам, запись полученного сальдо в новую таблицу. В дальнейшем при построении бухгалтерских отчетов начальное и конечное сальдо должно будет вычисляться на основании данных из этой таблицы.
Содержание |
Сальдо
Таблица в которую будет производится запись сгруппированных данных по проводкам будет называться AC_ENTRY_SALDO. Структура таблицы будет идентична структуре таблицы AC_ENTRY, за исключением некоторых полей:
CREATE TABLE AC_ENTRY_SALDO ( ID DINTKEY, COMPANYKEY DINTKEY, ACCOUNTKEY DINTKEY, DEBITNCU DCURRENCY, DEBITCURR DCURRENCY, DEBITEQ DCURRENCY, CREDITNCU DCURRENCY, CREDITCURR DCURRENCY, CREDITEQ DCURRENCY, CURRKEY DINTKEY, USR$GS_CUSTOMER USR$GS_DCUSTOMER, USR$FA_GROUPKEY USR$FA_CIPHERKEY, 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$GS_CONTRACT USR$INV_DCONTRACT, USR$GS_EXPENSES USR$GS_DEXPENSES, USR$GS_ECONOMICACTIVITY USR$DECONOMICACTIVITY, USR$GS_SALETAXRATE DCURRENCY,ENTRYDATE DDATE,RECORDKEY DMASTERKEY,TRANSACTIONKEY DINTKEY,DOCUMENTKEY DMASTERKEY,MASTERDOCKEY DINTKEY,ACCOUNTPART DACCOUNTPART,DISABLED DBOOLEAN DEFAULT 0,RESERVED DINTEGER,ISSIMPLE DBOOLEAN_NOTNULL NOT NULL);
Fieldname - поля аналитик
Fieldname – удаленные поля (по сравнению с AC_ENTRY)
При изменении структуры таблицы AC_ENTRY (в случае добавления новой аналитики), структура таблицы AC_ENTRY_SALDO также должна быть обновлена.
Сальдо в стандартных отчетах будет считаться исходя из AC_ENTRY_SALDO - AC_ENTRY. Например, мы хотим построить журнал-ордер на дату 01.05.2008. Сальдо будет вычислятся как сальдо из таблицы AC_ENTRY_SALDO минус сальдо за период 01.05.2008 - NOW рассчитанное по таблице AC_ENTRY старым методом.
После выполнения процедуры закрытия периода на таблицу AC_ENTRY должен быть повешен универсальный триггер AFTER INSERT OR UPDATE OR DELETE, который будет обновлять данные в таблице AC_ENTRY_SALDO в соответствии с изменениями в проводках. Здесь может возникнуть проблема блокировки, когда с базой работает несколько пользователей и одновременно создается несколько проводок, которые попадают в одну запись таблицы AC_ENTRY_SALDO. Поэтому было решено отказаться от обновления записей таблицы AC_ENTRY_SALDO в пользу добавления дельта-записей содержащих величину изменения сальдо по конкретному счету.
Например, в AC_ENTRY добавилась проводка:
Счет Дебет Кредит 51 1500 0
В таблице AC_ENTRY_SALDO по 51 счету содержится следующая запись:
Счет Дебет Кредит 51 25000 15000
Триггер на таблице AC_ENTRY вставит в таблицу AC_ENTRY_SALDO дельта-запись, данные примут вид:
Счет Дебет Кредит 51 25000 15000 51 1500 0
Предварительный текст триггера:
CREATE OR ALTER trigger ac_entry_do_saldo for ac_entry
active after insert or update or delete position 15
AS
BEGIN
IF (INSERTING AND (NEW.debitncu > 0) OR (NEW.debitcurr > 0) OR (NEW.creditncu > 0) OR (NEW.creditcurr > 0)) THEN
BEGIN
INSERT INTO AC_ENTRY_SALDO
(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.debitncu <> NEW.debitncu) OR (OLD.creditncu <> NEW.creditncu)
OR (OLD.debitcurr <> NEW.debitcurr) OR (OLD.creditcurr <> NEW.creditcurr)) THEN
BEGIN
INSERT INTO AC_ENTRY_SALDO
(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.debitncu > 0) OR (OLD.debitcurr > 0) OR (OLD.creditncu > 0) OR (OLD.creditcurr > 0)) THEN
BEGIN
INSERT INTO AC_ENTRY_SALDO
(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
Иногда будет необходимо перегруппировать данные в таблице AC_ENTRY_SALDO путем слияния первоначальной и дельта-записей в одну запись. Это можно делать каждый раз перед/после построения бухгалтерского отчета, или в период простоя Гедемина.
Стандартные отчеты
- Журнал-ордер
- Карта счета
- Анализ счета
- Главная книга
- Оборотная ведомость
Необходимо переделать механизм построения бухгалтерских отчетов с применением таблицы AC_ENTRY_SALDO и новых возможностей Firebird 2.5 (EXECUTE BLOCK)
Встроенные бухгалтерские функции
O(const AccDeb: WideString; const AccCred: WideString; BDate: TDateTime; EDate: TDateTime; const AnalyticsDeb: WideString; const AnalyticsCred: WideString): Currency V_O(const AccDeb, AccCred: WideString; BDate, EDate: TDateTime; const AnalyticsDeb, AnalyticsCred: WideString; CurrKey: Integer): Currency K_O(ValueKey: Integer; const AccDeb: WideString; const AccCred: WideString; BDate: TDateTime; EDate: TDateTime; const AnalyticsDeb: WideString; const AnalyticsCred: WideString): Currency
Корреспондентский оборот. Параметры: счет по дебету, счет по кредиту, дата начала, дата окончания, список имен и значений аналитик по дебету, список имен и значений аналитик по кредиту.
OD(const Account: WideString; BDate: TDateTime; EDate: TDateTime; const Analytics: WideString): Currency V_OD(const Account: WideString; BDate: TDateTime; EDate: TDateTime; const Analytics: WideString): Currency K_OD(ValueKey: Integer; const Account: WideString; BDate, EDate: TDateTime; const Analytics: WideString): Currency
Оборот дебетовый. Параметры: счет, дата начала, дата окончания, список имен и значений аналитик.
OK(const Account: WideString; BDate: TDateTime; EDate: TDateTime; const Analytics: WideString): Currency V_OK(const Account: WideString; BDate: TDateTime; EDate: TDateTime; const Analytics: WideString): Currency K_OK(ValueKey: Integer; const Account: WideString; BDate, EDate: TDateTime; const Analytics: WideString): Currency
Оборот кредитовый. Параметры: счет, дата начала, дата окончания, список имен и значений аналитик.
SD(const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency V_SD(const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency K_SD(ValueKey: Integer; const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency
Дебетовое сальдо. Параметры: счет, дата, список имен и значений аналитик.
SK(const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency V_SK(const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency K_SK(ValueKey: Integer; const Account: WideString; OnDate: TDateTime; const Analytics: WideString): Currency
Кредитовое сальдо. Параметры: счет, дата, список имен и значений аналитик.
Во всех этих и некоторых других закрытых методах класса TobjGSFunction необходимо поправить расчет сальдо с учетом таблицы AC_ENTRY_SALDO.
Другие макросы и отчеты
После реализации механизма закрытия периода, необходимо найти в макросах и отчетах код работы с таблицей AC_ENTRY и обновить его с учетом таблицы AC_ENTRY_SALDO.