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

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
(Решение)
(Глобальные отчеты и получение «закрытых» данных)
 
(не показаны 5 промежуточных версий 2 участников)
Строка 1: Строка 1:
 +
''См. также [[Перенос данных на чистую базу (постановка)]].''
 +
 
Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений.
 
Имеем базу данных, с которой требуется удалить старые документы и движение с формированием складских и бухгалтерских остатков по удаленным документам. Данные исходной базы должны остаться без изменений.
  
== Решение ==
+
Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода.
 +
Необходимо провести следующие действия:
  
Необходимо получить «чистую» базу, то есть базу без складских документов и проводок созданных ранее даты закрытия периода. Есть три пути:
+
# Копируем исходную базу данных A в закрываемую B (делаем backup-restore в закрываемую базу)
# копирование исходной базы А в файл базы Б, и последующее удаление данных старше указанной даты закрытия периода с базы Б, затем перенос складских и бухгалтерских остатков на дату закрытия с базы А на Б
+
# Заходим в базу B и запускаем процедуру закрытия периода
# формирование базы Б – копии базы данных А, но без данных, и последующий перенос на базу Б складских и бухгалтерских остатков на дату закрытия, а также документов и проводок созданных после даты закрытия периода с базы А (+ все остальные необходимые справочники и нескладские документы)
+
# копирование исходной базы А в файл базы Б (в смысле делаем backup-restore в базу Б), последующее формирование бухгалтерских и складских остатков на дату закрытия периода прямо на базе Б, удаление складских документов и проводок с базы Б созданных до даты закрытия периода.
+
 
+
Предполагается давать возможность выбора: 
+
* типов закрываемых документов, то есть документов, по которым будет формироваться складской и бухгалтерский остаток, и из которых затем будут удаляться устаревшие записи.
+
* бухгалтерских аналитик и складских признаков карточки по которым будет происходить группировка остатков. Например, при формировании складского остатка нам не нужны признаки карточки привязывающие движение к конкретной позиции документа (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
+
)
+
 
+
 
+
Разовьем 3-ий способ закрытия периода.
+
# Заходим в базу Б и запускаем процедуру закрытия периода
+
 
# Формируется бухгалтерский остаток на дату {CLOSEDATE - 1}
 
# Формируется бухгалтерский остаток на дату {CLOSEDATE - 1}
 
# Удаляем проводки, по которым сформировался остаток
 
# Удаляем проводки, по которым сформировался остаток
 
# Сохраняем бухгалтерский остаток как проводки на дату {CLOSEDATE - 1}
 
# Сохраняем бухгалтерский остаток как проводки на дату {CLOSEDATE - 1}
 
# Формируем складской остаток на дату {CLOSEDATE - 1}
 
# Формируем складской остаток на дату {CLOSEDATE - 1}
 +
# Сохраняем складской остаток в документе прихода [[INV_DOCUMENT]] с датой равной {CLOSEDATE - 1}
 
# Перепривязываем складские карточки
 
# Перепривязываем складские карточки
 
# Удаляем документы, по которым сформировался складской остаток
 
# Удаляем документы, по которым сформировался складской остаток
# Сохраняем складской остаток в документе прихода [[INV_DOCUMENT]] с датой равной {CLOSEDATE - 1}
 
 
# Перестроить оперативную информацию по проводкам в таблице [[AC_ENTRY_BALANCE]] (при удалении и вставке проводок появится много лишних записей)
 
# Перестроить оперативную информацию по проводкам в таблице [[AC_ENTRY_BALANCE]] (при удалении и вставке проводок появится много лишних записей)
 
# Установим генератор {generator name} в значение {CLOSEDATE} (предполагается в дальнейшем использовать эту дату при построении комплексных отчетов по данным находящимся в новой и старой базе)
 
# Установим генератор {generator name} в значение {CLOSEDATE} (предполагается в дальнейшем использовать эту дату при построении комплексных отчетов по данным находящимся в новой и старой базе)
  
Складские остатки формируются путем группировки всех складских движений предшествующих дате закрытия периода. Для хранения сформированных складских остатков предполагается создать складской документ INV_DOCUMENT, который обладает всеми признаками новой карточки, и приходует товар на подразделение нашей организации с Псевдоклиента. По документу [[INV_DOCUMENT]] не должно быть настроено никаких автоматических операций.
+
Предполагается давать пользователю возможность выбора: 
 +
* типов складских документов, которые необходимо оставить нетронутыми, то есть, не удалять из них записи в процессе закрытия  
 +
* складских признаков карточки по которым будет происходить группировка остатков. Например, при формировании складского остатка нам не нужны признаки карточки привязывающие движение к конкретной позиции документа (USR$INV_ADDLINEKEY – ссылка на документ прихода).
  
Бухгалтерские остатки формируются путем группировки всех проводок за период предшествующий дате закрытия периода. Сформированные бухгалтерские остатки предполагается вставлять в таблицу [[AC_ENTRY]] (+ [[AC_RECORD]]) как проводки на дату закрытия периода.
+
Под датой {CLOSEDATE} закрытия периода понимается дата, начиная с которой на новой базе будут идти уже не сгруппированные документы и проводки. Расчет бухгалтерского и складского остатков будет производиться на дату {CLOSEDATE - 1}
Удаление устаревших проводок проходит просто, необходимо только правильно ограничить запрос на удаление (дата, типы документов).
+
При удалении устаревших документов удаляются и складские карточки созданные позициями этих документов, но более новые карточки из движения могут ссылаться на эти, удаляемые, карточки (по полю PARENT). Значит необходима перепривязка новых (с датой создания >= {CLOSEDATE}) складских карточек к карточкам созданным документом INV_DOCUMENT, то есть к карточкам по сформированному складскому остатку.
+
  
SELECT
+
Предполагается возможность неоднократного закрытия периода, то есть возможность повторения процесса закрытия периода на основе текущей базы, полученной ранее в процессе полного закрытия периода. Данная информация будет необходима при построении отчетов за период, охватывающий несколько баз данных. Историю закрытий предполагается накапливать в таблице:
 +
 
 +
<source lang="sql">
 +
CREATE TABLE DB_CLOSEHISTORY (
 +
  id dintkey,
 +
  databasepath varchar(2048),
 +
  server varchar(255),
 +
  user varchar(31),
 +
  password varchar(31),
 +
  closedate date
 +
)
 +
 
 +
</source>
 +
 
 +
= Формирование бухгалтерского сальдо =
 +
 
 +
Бухгалтерские остатки формируются путем группировки всех проводок за период предшествующий дате закрытия периода. Сформированные бухгалтерские остатки предполагается вставлять в таблицу [[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: Строка 66:
 
   c_more.FIRSTDOCUMENTKEY,
 
   c_more.FIRSTDOCUMENTKEY,
 
   c_more.FIRSTDATE
 
   c_more.FIRSTDATE
FROM
+
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
+
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
+
EXECUTE BLOCK
(
+
(
  closedate DATE = :closedate
+
  closedate DATE = :closedate
)
+
)
AS
+
AS
 
   DECLARE VARIABLE mid INTEGER;
 
   DECLARE VARIABLE mid INTEGER;
 
   DECLARE VARIABLE cardkey INTEGER;
 
   DECLARE VARIABLE cardkey INTEGER;
Строка 84: Строка 96:
 
   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
+
BEGIN
 
   FOR
 
   FOR
 
     SELECT
 
     SELECT
Строка 139: Строка 151:
 
     END
 
     END
 
   END
 
   END
END
+
END
 
</source>
 
</source>
  
=== Глобальные отчеты и получение «закрытых» данных ===
+
= Глобальные отчеты и получение «закрытых» данных =
 
После полного закрытия периода может возникнуть необходимость в построении отчета, или получении данных одновременно с текущей рабочей базы, и уже закрытой архивной базы (баз). Предполагается создать новый бизнес-объект {TgdcDatabaseCloseHistory} представляющий информацию из таблицы {DB_CLOSEHISTORY}. Через функцию объекта:
 
После полного закрытия периода может возникнуть необходимость в построении отчета, или получении данных одновременно с текущей рабочей базы, и уже закрытой архивной базы (баз). Предполагается создать новый бизнес-объект {TgdcDatabaseCloseHistory} представляющий информацию из таблицы {DB_CLOSEHISTORY}. Через функцию объекта:
  
function GetDatabaseList(ActualDateBegin, ActualDateEnd: TDateTime): TStringList
+
<source lang="delphi">
 +
function GetDatabaseList(ActualDateBegin, ActualDateEnd: TDateTime): TStringList
 +
 
 +
</source>
  
 
, указав значения дат по которым необходимо построить отчет или получить данные, можно будет получить список баз данных (с путями) которые необходимо задействовать в данном отчете. Список баз будет отсортирован по дате закрытия, начиная с самой старой базы.
 
, указав значения дат по которым необходимо построить отчет или получить данные, можно будет получить список баз данных (с путями) которые необходимо задействовать в данном отчете. Список баз будет отсортирован по дате закрытия, начиная с самой старой базы.
 
Получив список закрытых баз программист может получить данные с внешней базы либо при помощи создания транзакции к внешней базе, либо при помощи конструкции EXECUTE STATEMENT, которая, начиная с FB 2.5 может обращаться к внешней базе.
 
Получив список закрытых баз программист может получить данные с внешней базы либо при помощи создания транзакции к внешней базе, либо при помощи конструкции EXECUTE STATEMENT, которая, начиная с FB 2.5 может обращаться к внешней базе.
[FOR] EXECUTE STATEMENT <query_text> [(<input_parameters>)]
+
<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]
Строка 157: Строка 173:
 
   [INTO <variables>]
 
   [INTO <variables>]
  
[[Category:Постановка]]
+
</source>
 +
 
 +
[[Category:Постановка-Сделано]]

Текущая версия на 14:48, 2 апреля 2014

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

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

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

  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>]
Персональные инструменты
Пространства имён

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