Полное закрытие периода (постановка)
SYSDBA (обсуждение | вклад) |
SYSDBA (обсуждение | вклад) (→Глобальные отчеты и получение «закрытых» данных) |
||
| Строка 175: | Строка 175: | ||
</source> | </source> | ||
| − | [[Category:Постановка]] | + | [[Category:Постановка-Сделано]] |
Текущая версия на 14:48, 2 апреля 2014
См. также Перенос данных на чистую базу (постановка).
Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений.
Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода. Необходимо провести следующие действия:
- Копируем исходную базу данных 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>]