Полное закрытие периода (постановка)

Материал из GedeminWiki
Перейти к: навигация, поиск

См. также Перенос данных на чистую базу (постановка).

Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений.

Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода. Необходимо провести следующие действия:

  1. Копируем исходную базу данных A в закрываемую B (делаем backup-restore в закрываемую базу)
  2. Заходим в базу B и запускаем процедуру закрытия периода
  3. Формируется бухгалтерский остаток на дату {CLOSEDATE - 1}
  4. Удаляем проводки, по которым сформировался остаток
  5. Сохраняем бухгалтерский остаток как проводки на дату {CLOSEDATE - 1}
  6. Формируем складской остаток на дату {CLOSEDATE - 1}
  7. Сохраняем складской остаток в документе прихода INV_DOCUMENT с датой равной {CLOSEDATE - 1}
  8. Перепривязываем складские карточки
  9. Удаляем документы, по которым сформировался складской остаток
  10. Перестроить оперативную информацию по проводкам в таблице AC_ENTRY_BALANCE (при удалении и вставке проводок появится много лишних записей)
  11. Установим генератор {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>]
Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты