Полное закрытие периода (постановка)
SYSDBA (обсуждение | вклад) (→Решение) |
Flake (обсуждение | вклад) (→Решение) |
||
| Строка 1: | Строка 1: | ||
Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений. | Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений. | ||
| − | + | Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода. | |
| + | Необходимо провести следующие действия: | ||
| − | + | # Копируем исходную базу данных A в закрываемую B (делаем backup-restore в закрываемую базу) | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | Предполагается давать возможность выбора: | + | # Заходим в базу B и запускаем процедуру закрытия периода |
| − | * типов | + | |
| − | * | + | # Формируется бухгалтерский остаток на дату {CLOSEDATE - 1} |
| + | |||
| + | # Удаляем проводки, по которым сформировался остаток | ||
| + | # Сохраняем бухгалтерский остаток как проводки на дату {CLOSEDATE - 1} | ||
| + | # Формируем складской остаток на дату {CLOSEDATE - 1} | ||
| + | |||
| + | # Сохраняем складской остаток в документе прихода [[INV_DOCUMENT]] с датой равной {CLOSEDATE - 1} | ||
| + | # Перепривязываем складские карточки | ||
| + | # Удаляем документы, по которым сформировался складской остаток | ||
| + | |||
| + | # Перестроить оперативную информацию по проводкам в таблице [[AC_ENTRY_BALANCE]] (при удалении и вставке проводок появится много лишних записей) | ||
| + | # Установим генератор {generator name} в значение {CLOSEDATE} (предполагается в дальнейшем использовать эту дату при построении комплексных отчетов по данным находящимся в новой и старой базе) | ||
| + | Предполагается давать пользователю возможность выбора: | ||
| + | * типов складских документов, которые необходимо оставить нетронутыми, то есть, не удалять из них записи в процессе закрытия | ||
| + | * складских признаков карточки по которым будет происходить группировка остатков. Например, при формировании складского остатка нам не нужны признаки карточки привязывающие движение к конкретной позиции документа (USR$INV_ADDLINEKEY – ссылка на документ прихода). | ||
Под датой {CLOSEDATE} закрытия периода понимается дата, начиная с которой на новой базе будут идти уже не сгруппированные документы и проводки. Расчет бухгалтерского и складского остатков будет производиться на дату {CLOSEDATE - 1} | Под датой {CLOSEDATE} закрытия периода понимается дата, начиная с которой на новой базе будут идти уже не сгруппированные документы и проводки. Расчет бухгалтерского и складского остатков будет производиться на дату {CLOSEDATE - 1} | ||
| Строка 25: | Строка 37: | ||
) | ) | ||
| + | = Формирование бухгалтерского сальдо = | ||
| − | + | Бухгалтерские остатки формируются путем группировки всех проводок за период предшествующий дате закрытия периода. Сформированные бухгалтерские остатки предполагается вставлять в таблицу [[AC ENTRY]] (+ [[AC RECORD]]) как проводки на дату закрытия периода. | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | = Удаление устаревших проводок = | |
| − | + | Удаление устаревших проводок проходит просто, необходимо только правильно ограничить запрос на удаление (дата закрытия, типы неудаляемых документов). | |
| − | Удаление устаревших проводок проходит просто, необходимо только правильно ограничить запрос на удаление (дата, типы документов) | + | |
| − | + | ||
| − | + | = Формирование складских остатков = | |
| + | |||
| + | Складские остатки формируются путем группировки всех складских движений предшествующих дате закрытия периода в разрезе выбранных пользователем складских признаков. Для хранения сформированных складских остатков предполагается создать складской документ INV_DOCUMENT, который обладает всеми признаками новой карточки, и приходует товар на подразделение нашей организации. Если найден поставщик по конкретному ТМЦ, то приход оформляется с него, иначе приходуем с Псевдоклиента. По документу [[INV DOCUMENT]] не должно быть настроено никаких автоматических операций. | ||
| + | = Перепривязка складские карточки = | ||
| + | |||
| + | При удалении устаревших документов удаляются и складские карточки созданные позициями этих документов, но более новые карточки из движения могут ссылаться на эти, удаляемые, карточки (по полю PARENT). Также остаются ссылки DOCUMENTKEY, FIRSTDOCUMENTKEY и поля складских признаков, которые могут ссылаться на удаляемые документы. Значит необходима перепривязка новых (с датой создания >= {CLOSEDATE}) складских карточек к карточкам созданным документом INV_DOCUMENT, то есть к карточкам по сформированному складскому остатку. | ||
| + | <source lang="sql"> | ||
| + | SELECT | ||
m_less.movementdate, | m_less.movementdate, | ||
c_less.ID, | c_less.ID, | ||
| Строка 57: | Строка 65: | ||
c_more.FIRSTDOCUMENTKEY, | c_more.FIRSTDOCUMENTKEY, | ||
c_more.FIRSTDATE | c_more.FIRSTDATE | ||
| − | + | FROM | |
inv_card c_less | inv_card c_less | ||
JOIN inv_card c_more ON c_more.parent = c_less.id | JOIN inv_card c_more ON c_more.parent = c_less.id | ||
JOIN inv_movement m_less ON m_less.cardkey = c_less.id | JOIN inv_movement m_less ON m_less.cardkey = c_less.id | ||
JOIN inv_movement m_more ON m_more.cardkey = c_more.id | JOIN inv_movement m_more ON m_more.cardkey = c_more.id | ||
| − | + | WHERE | |
m_less.movementdate < :closedate | m_less.movementdate < :closedate | ||
AND m_more.movementdate >= :closedate | AND m_more.movementdate >= :closedate | ||
| + | |||
| + | </source> | ||
Во всех карточках c_more полученных из этого запроса надо переставить поле PARENT на карточки по документу INV_DOCUMENT. Соответствие карточек определяется на основе выбранных пользователем актуальных признаков складских карточек. Те же самые изменения произвести с записями m_more, но изменять надо поле CARDKEY. | Во всех карточках c_more полученных из этого запроса надо переставить поле PARENT на карточки по документу INV_DOCUMENT. Соответствие карточек определяется на основе выбранных пользователем актуальных признаков складских карточек. Те же самые изменения произвести с записями m_more, но изменять надо поле CARDKEY. | ||
Перепривязка карточек выполняется после формирования складского остатка, и до удаления устаревших документов. | Перепривязка карточек выполняется после формирования складского остатка, и до удаления устаревших документов. | ||
| + | = Удаление устаревших документов = | ||
Список документов подлежащих удалению получим по ссылкам DOCUMENTKEY таблицы INV_MOVEMENT, на основе которой формируется складской остаток. Выполняем запрос с такими же ограничениями что и при формировании складского остатка (дата, типы документов), но без группировки. | Список документов подлежащих удалению получим по ссылкам DOCUMENTKEY таблицы INV_MOVEMENT, на основе которой формируется складской остаток. Выполняем запрос с такими же ограничениями что и при формировании складского остатка (дата, типы документов), но без группировки. | ||
<source lang="sql"> | <source lang="sql"> | ||
| − | + | EXECUTE BLOCK | |
| − | + | ( | |
| − | + | closedate DATE = :closedate | |
| − | + | ) | |
| − | + | AS | |
DECLARE VARIABLE mid INTEGER; | DECLARE VARIABLE mid INTEGER; | ||
DECLARE VARIABLE cardkey INTEGER; | DECLARE VARIABLE cardkey INTEGER; | ||
| Строка 84: | Строка 95: | ||
DECLARE VARIABLE rel_name_line VARCHAR(31); | DECLARE VARIABLE rel_name_line VARCHAR(31); | ||
DECLARE VARIABLE Sql VARCHAR(1024); | DECLARE VARIABLE Sql VARCHAR(1024); | ||
| − | + | BEGIN | |
FOR | FOR | ||
SELECT | SELECT | ||
| Строка 139: | Строка 150: | ||
END | END | ||
END | END | ||
| − | + | END | |
</source> | </source> | ||
| − | + | = Глобальные отчеты и получение «закрытых» данных = | |
После полного закрытия периода может возникнуть необходимость в построении отчета, или получении данных одновременно с текущей рабочей базы, и уже закрытой архивной базы (баз). Предполагается создать новый бизнес-объект {TgdcDatabaseCloseHistory} представляющий информацию из таблицы {DB_CLOSEHISTORY}. Через функцию объекта: | После полного закрытия периода может возникнуть необходимость в построении отчета, или получении данных одновременно с текущей рабочей базы, и уже закрытой архивной базы (баз). Предполагается создать новый бизнес-объект {TgdcDatabaseCloseHistory} представляющий информацию из таблицы {DB_CLOSEHISTORY}. Через функцию объекта: | ||
| Строка 149: | Строка 160: | ||
, указав значения дат по которым необходимо построить отчет или получить данные, можно будет получить список баз данных (с путями) которые необходимо задействовать в данном отчете. Список баз будет отсортирован по дате закрытия, начиная с самой старой базы. | , указав значения дат по которым необходимо построить отчет или получить данные, можно будет получить список баз данных (с путями) которые необходимо задействовать в данном отчете. Список баз будет отсортирован по дате закрытия, начиная с самой старой базы. | ||
Получив список закрытых баз программист может получить данные с внешней базы либо при помощи создания транзакции к внешней базе, либо при помощи конструкции EXECUTE STATEMENT, которая, начиная с FB 2.5 может обращаться к внешней базе. | Получив список закрытых баз программист может получить данные с внешней базы либо при помощи создания транзакции к внешней базе, либо при помощи конструкции EXECUTE STATEMENT, которая, начиная с FB 2.5 может обращаться к внешней базе. | ||
| − | + | <source lang="sql"> | |
| + | [FOR] EXECUTE STATEMENT <query_text> [(<input_parameters>)] | ||
[ON EXTERNAL [DATA SOURCE] <connection_string>] | [ON EXTERNAL [DATA SOURCE] <connection_string>] | ||
[WITH {AUTONOMOUS | COMMON} TRANSACTION] | [WITH {AUTONOMOUS | COMMON} TRANSACTION] | ||
| Строка 156: | Строка 168: | ||
[WITH CALLER PRIVILEGES] | [WITH CALLER PRIVILEGES] | ||
[INTO <variables>] | [INTO <variables>] | ||
| + | |||
| + | </source> | ||
[[Category:Постановка]] | [[Category:Постановка]] | ||
Версия 15:52, 14 июля 2009
Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений.
Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода. Необходимо провести следующие действия:
- Копируем исходную базу данных A в закрываемую B (делаем backup-restore в закрываемую базу)
- Заходим в базу B и запускаем процедуру закрытия периода
- Формируется бухгалтерский остаток на дату {CLOSEDATE - 1}
- Удаляем проводки, по которым сформировался остаток
- Сохраняем бухгалтерский остаток как проводки на дату {CLOSEDATE - 1}
- Формируем складской остаток на дату {CLOSEDATE - 1}
- Сохраняем складской остаток в документе прихода INV_DOCUMENT с датой равной {CLOSEDATE - 1}
- Перепривязываем складские карточки
- Удаляем документы, по которым сформировался складской остаток
- Перестроить оперативную информацию по проводкам в таблице AC_ENTRY_BALANCE (при удалении и вставке проводок появится много лишних записей)
- Установим генератор {generator name} в значение {CLOSEDATE} (предполагается в дальнейшем использовать эту дату при построении комплексных отчетов по данным находящимся в новой и старой базе)
Предполагается давать пользователю возможность выбора:
- типов складских документов, которые необходимо оставить нетронутыми, то есть, не удалять из них записи в процессе закрытия
- складских признаков карточки по которым будет происходить группировка остатков. Например, при формировании складского остатка нам не нужны признаки карточки привязывающие движение к конкретной позиции документа (USR$INV_ADDLINEKEY – ссылка на документ прихода).
Под датой {CLOSEDATE} закрытия периода понимается дата, начиная с которой на новой базе будут идти уже не сгруппированные документы и проводки. Расчет бухгалтерского и складского остатков будет производиться на дату {CLOSEDATE - 1}
Предполагается возможность неоднократного закрытия периода, то есть возможность повторения процесса закрытия периода на основе текущей базы, полученной ранее в процессе полного закрытия периода. Данная информация будет необходима при построении отчетов за период, охватывающий несколько баз данных. Историю закрытий предполагается накапливать в таблице:
CREATE TABLE DB_CLOSEHISTORY ??? ( id dintkey, databasepath varchar(2048), server varchar(255), user varchar(31), password varchar(31), closedate date )
Содержание |
Формирование бухгалтерского сальдо
Бухгалтерские остатки формируются путем группировки всех проводок за период предшествующий дате закрытия периода. Сформированные бухгалтерские остатки предполагается вставлять в таблицу AC ENTRY (+ AC RECORD) как проводки на дату закрытия периода.
Удаление устаревших проводок
Удаление устаревших проводок проходит просто, необходимо только правильно ограничить запрос на удаление (дата закрытия, типы неудаляемых документов).
Формирование складских остатков
Складские остатки формируются путем группировки всех складских движений предшествующих дате закрытия периода в разрезе выбранных пользователем складских признаков. Для хранения сформированных складских остатков предполагается создать складской документ INV_DOCUMENT, который обладает всеми признаками новой карточки, и приходует товар на подразделение нашей организации. Если найден поставщик по конкретному ТМЦ, то приход оформляется с него, иначе приходуем с Псевдоклиента. По документу INV DOCUMENT не должно быть настроено никаких автоматических операций.
Перепривязка складские карточки
При удалении устаревших документов удаляются и складские карточки созданные позициями этих документов, но более новые карточки из движения могут ссылаться на эти, удаляемые, карточки (по полю PARENT). Также остаются ссылки DOCUMENTKEY, FIRSTDOCUMENTKEY и поля складских признаков, которые могут ссылаться на удаляемые документы. Значит необходима перепривязка новых (с датой создания >= {CLOSEDATE}) складских карточек к карточкам созданным документом INV_DOCUMENT, то есть к карточкам по сформированному складскому остатку.
SELECT m_less.movementdate, c_less.ID, c_less.PARENT, c_less.DOCUMENTKEY, c_less.FIRSTDOCUMENTKEY, c_less.FIRSTDATE, m_more.movementdate, c_more.ID, c_more.PARENT, c_more.DOCUMENTKEY, c_more.FIRSTDOCUMENTKEY, c_more.FIRSTDATE FROM inv_card c_less JOIN inv_card c_more ON c_more.parent = c_less.id JOIN inv_movement m_less ON m_less.cardkey = c_less.id JOIN inv_movement m_more ON m_more.cardkey = c_more.id WHERE m_less.movementdate < :closedate AND m_more.movementdate >= :closedate
Во всех карточках c_more полученных из этого запроса надо переставить поле PARENT на карточки по документу INV_DOCUMENT. Соответствие карточек определяется на основе выбранных пользователем актуальных признаков складских карточек. Те же самые изменения произвести с записями m_more, но изменять надо поле CARDKEY.
Перепривязка карточек выполняется после формирования складского остатка, и до удаления устаревших документов.
Удаление устаревших документов
Список документов подлежащих удалению получим по ссылкам DOCUMENTKEY таблицы INV_MOVEMENT, на основе которой формируется складской остаток. Выполняем запрос с такими же ограничениями что и при формировании складского остатка (дата, типы документов), но без группировки.
EXECUTE BLOCK ( closedate DATE = :closedate ) AS DECLARE VARIABLE mid INTEGER; DECLARE VARIABLE cardkey INTEGER; DECLARE VARIABLE dockey INTEGER; DECLARE VARIABLE headdockey INTEGER; DECLARE VARIABLE rel_name_head VARCHAR(31); DECLARE VARIABLE rel_name_line VARCHAR(31); DECLARE VARIABLE SQL VARCHAR(1024); BEGIN FOR SELECT m.id, m.cardkey, m.documentkey FROM inv_movement m /*WHERE m.movementdate < :closedate */ ORDER BY m.movementdate DESC, m.id DESC INTO :mid, :cardkey, :dockey DO BEGIN SELECT line.relationname, head.relationname FROM gd_document doc JOIN gd_documenttype t ON t.id = doc.documenttypekey JOIN at_relations line ON line.id = t.linerelkey JOIN at_relations head ON head.id = t.headerrelkey WHERE doc.id = :dockey INTO :rel_name_line, rel_name_head; SELECT parent FROM gd_document WHERE id = :dockey INTO :headdockey; -- удалим позицию документа SQL = 'DELETE FROM ' || :rel_name_line || ' WHERE documentkey = ' || CAST(:dockey AS VARCHAR(20)); EXECUTE STATEMENT SQL; DELETE FROM gd_document WHERE id = :dockey; -- если шапка стала пустой удалим и ее SQL = 'SELECT h.documentkey FROM ' || :rel_name_head || ' h WHERE h.documentkey = '; SQL = SQL || CAST(:headdockey AS VARCHAR(20)) || ' AND NOT EXISTS (SELECT l.documentkey FROM '; SQL = SQL || :rel_name_line ||' l WHERE l.masterkey = h.documentkey )'; FOR EXECUTE STATEMENT SQL INTO :dockey DO BEGIN SQL = 'DELETE FROM ' || :rel_name_head || ' WHERE documentkey = ' || CAST(:dockey AS VARCHAR(20)); EXECUTE STATEMENT SQL; DELETE FROM ac_entry WHERE (documentkey = :dockey) OR (masterdockey = :dockey) OR (usr$gs_document = :dockey); DELETE FROM gd_document WHERE id = :dockey; END END END
Глобальные отчеты и получение «закрытых» данных
После полного закрытия периода может возникнуть необходимость в построении отчета, или получении данных одновременно с текущей рабочей базы, и уже закрытой архивной базы (баз). Предполагается создать новый бизнес-объект {TgdcDatabaseCloseHistory} представляющий информацию из таблицы {DB_CLOSEHISTORY}. Через функцию объекта:
function GetDatabaseList(ActualDateBegin, ActualDateEnd: TDateTime): TStringList
, указав значения дат по которым необходимо построить отчет или получить данные, можно будет получить список баз данных (с путями) которые необходимо задействовать в данном отчете. Список баз будет отсортирован по дате закрытия, начиная с самой старой базы. Получив список закрытых баз программист может получить данные с внешней базы либо при помощи создания транзакции к внешней базе, либо при помощи конструкции EXECUTE STATEMENT, которая, начиная с FB 2.5 может обращаться к внешней базе.
[FOR] EXECUTE STATEMENT <query_text> [(<input_parameters>)] [ON EXTERNAL [DATA SOURCE] <connection_string>] [WITH {AUTONOMOUS | COMMON} TRANSACTION] [AS USER <user_name>] [PASSWORD <password>] [WITH CALLER PRIVILEGES] [INTO <variables>]