Регістри в K2 ERP: відмінності між версіями

Немає опису редагування
Немає опису редагування
Рядок 66: Рядок 66:
</pre>
</pre>


=== Застереження щодо Extension:Diagrams ===
=== Вимоги до версії та смоук-тест ===


{{Note|'''Перевірити до затвердження документа.''' Станом на дату складання ТЗ офіційна сторінка розширення вказує: статус — '''beta''', остання версія '''0.10.0 від 12.06.2022''', задекларована сумісність '''MediaWiki 1.34–1.39'''. Політика розширення — «master зберігає зворотну сумісність», тож на новіших версіях (1.43 LTS і далі) воно, найімовірніше, працює, але це '''не підтверджено''' і підлягає перевірці на цільовій корпоративній вікі. Актуальний стан — <nowiki>https://www.mediawiki.org/wiki/Extension:Diagrams</nowiki>.}}
{{Note|'''Мінімальна версія — 1.0.0''' (реліз від 15.03.2026). Саме в ній додано <code>$wgDiagramsDefaultFormat</code>, без якого документ рендериться в PNG і ER-діаграми розділу 9 стають нечитабельними. Автор супроводжує підняття мажорної версії до 1 формулюванням, що проєкт вийшов на стабільність.}}


{{Note|'''Тег PlantUML називається <code><nowiki><uml></nowiki></code>''', а не <code><nowiki><plantuml></nowiki></code> (як в окремому Extension:PlantUML). Розмітка документа використовує саме <code><nowiki><uml></nowiki></code>.}}
{{Note|'''Інфобокс на mediawiki.org станом на дату складання ТЗ застарілий''' — показує версію 0.10.0 (2022) і сумісність «MediaWiki ≤ 1.39», тоді як у репозиторії 27 релізів і остання — 1.0.0 від 15.03.2026. '''Джерело істини — GitHub''' (<nowiki>https://github.com/samwilson/diagrams-extension/releases</nowiki>), а не інфобокс вікі-сторінки. Обмеження «≤ 1.39» перевіряти не за сторінкою, а за <code>extension.json</code> актуального релізу.}}
 
Перед публікацією документа прогнати смоук-тест на цільовій вікі — по одному представнику кожного типу:
 
{| class="wikitable"
! # !! Що перевіряємо !! Де в документі !! Ознака успіху
|-
| 1 || <code><nowiki><graphviz></nowiki></code>, <code>rankdir</code>, <code>shape=record</code>, кластери || 5.1, 8.8, 9.5, Д.1, Д.8 || Діаграма рендериться, підписи не обрізані
|-
| 2 || <code><nowiki><uml></nowiki></code> + <code>@startuml</code>, <code>entity</code>, <code>skinparam linetype ortho</code> || 9.1–9.4 || ER-модель із колонками та позначками PK/FK
|-
| 3 || '''<code><nowiki><uml></nowiki></code> + <code>@startgantt</code>''' || '''7.5.1''' || Діаграма Ганта. '''Головний ризик:''' якщо розширення обгортає вміст у <code>@startuml</code> автоматично, <code>@startgantt</code> не спрацює
|-
| 4 || <code>$wgDiagramsDefaultFormat = 'svg'</code> || будь-яка || У HTML-коді сторінки <code>&lt;img src="…<b>.svg</b>"&gt;</code>, а не <code>.png</code>
|-
| 5 || Кирилиця в підписах вузлів || 5.1, 6.1 || Немає «квадратиків» — на сервері є потрібні шрифти
|}
 
{{Note|'''Щодо п. 3.''' Документ використовує явні роздільники <code>@startuml…@enduml</code> / <code>@startgantt…@endgantt</code> всередині тегів. Це відповідає нормалізованій поведінці PlantUML: розробники вимагають <code>@startXYZ</code> усюди, зокрема з прапорцем <code>-pipe</code>, а можливість опускати роздільник збережена лише як застаріла опція для сумісності зі старими скриптами. '''Перевірити на смоук-тесті''' я не мав змоги — це єдине непідтверджене припущення в розділі. Якщо <code>@startgantt</code> не відрендериться, замінити діаграму 7.5.1 на <code><nowiki><graphviz></nowiki></code> або повернути ASCII-схему з історії правок.}}


=== Альтернативи та запасний варіант ===
=== Альтернативи та запасний варіант ===
Рядок 77: Рядок 95:
! Варіант !! Оцінка
! Варіант !! Оцінка
|-
|-
| '''Extension:Diagrams''' ''(обрано)'' || Одне розширення на обидва формати; не зберігає рендери як файли вікі; є дві реалізації сервісу рендерингу — PHP (Symfony) та '''Python''' (остання узгоджується зі стеком проєкту, розділ 4.3). Мінус — beta-статус і питання сумісності вище.
| '''Extension:Diagrams ≥ 1.0.0''' ''(обрано)'' || Одне розширення на всі формати документа; не зберігає рендери як файли вікі; є дві реалізації сервісу рендерингу — PHP (Symfony) та '''Python''' (остання узгоджується зі стеком проєкту, розділ 4.3).
|-
|-
| Extension:GraphViz + Extension:PlantUML окремо || '''Не рекомендується.''' Extension:GraphViz за даними трекера Wikimedia не підтримується й потребує правок для роботи з актуальними версіями MediaWiki. Два розширення замість одного.
| Extension:GraphViz + Extension:PlantUML окремо || '''Не рекомендується.''' Extension:GraphViz за даними трекера Wikimedia не супроводжується й потребує правок для роботи з актуальними версіями MediaWiki. Два розширення замість одного.
|-
|-
| Mermaid (<code><nowiki><mermaid></nowiki></code> у Diagrams або Extension:Mermaid) || Рендериться на клієнті, не потребує бінарників. Але <code>erDiagram</code> Mermaid суттєво менш виразний за <code>entity</code> PlantUML: ER-моделі розділу 9 містять типи, ознаки PK/FK та коментарі до полів — це не переноситься без втрат. Придатний як запасний варіант для простих схем (5.1, Д.1).
| Mermaid (<code><nowiki><mermaid></nowiki></code> у складі Diagrams або Extension:Mermaid) || Рендериться на клієнті, не потребує бінарників на сервері. Але <code>erDiagram</code> Mermaid суттєво менш виразний за <code>entity</code> PlantUML: ER-моделі розділу 9 містять типи, ознаки PK/FK та коментарі до полів — це не переноситься без втрат. Придатний для простих схем (5.1, Д.1).
|-
|-
| Без розширень || Блоки діаграм відображатимуться як вихідний текст. Документ залишається читабельним: ключові механізми продубльовані ASCII-схемами (розділи 6.1, 7.4.1, 7.5.1, 8.8, Д.9, Е.8).
| Без розширень || Блоки діаграм відображатимуться як вихідний текст. '''Документ втрачає 9 із 12 схем''' — на відміну від версій ≤ 1.2, ASCII-дублів більше немає (див. нижче).
|}
 
=== Що навмисно залишено ASCII-схемами ===
 
Після переходу на Diagrams дублювання «діаграма + ASCII» прибрано: воно розходилося при правках. Але 8 блоків <code><nowiki><pre></nowiki></code> залишено свідомо — для них Diagrams не дає виграшу:
 
{| class="wikitable"
! Розділ !! Блок !! Чому не діаграма
|-
| 6.8.1–6.8.3 || Макети конструктора || PlantUML має <code>@startsalt</code> для wireframe'ів, але ASCII тут '''комунікує краще''': він явно читається як ескіз і не створює хибного враження затвердженого дизайну. Salt додає рендер-ризик без користі.
|-
| 7.4.1 || Timeline підсумків і ТА || Схема несе формулу («Залишок = Підсумок(P) + Σ рухів») поряд із віссю часу. Gantt це не передає, а <code>@startuml</code> timing — надмірність.
|-
| Д.9 || Наскрізний розрахунок ЗП || Це покроковий наратив із числами, а не структура. Діаграма не додасть змісту.
|-
| Д.11, Е.8 || Чек-лист і дерево репозиторію || Список і файлове дерево. <code><nowiki><pre></nowiki></code> — рівно те, що треба.
|}
|}


Рядок 379: Рядок 413:
== 6.1. Місце в репозиторії метаданих ==
== 6.1. Місце в репозиторії метаданих ==


<pre>
<graphviz>
Конфігурація K2 ERP
digraph ConfigTree {
├── Довідники
  rankdir=LR; bgcolor="transparent"; ranksep=0.35; nodesep=0.12;
├── Документи
  node [shape=box, style="filled,rounded", fontname="Helvetica", fontsize=9, height=0.28];
├── Плани рахунків             ← використовується РБ
  edge [arrowhead=none, color="#9e9e9e"];
├── Плани видів характеристик  ← використовується як тип субконто / вимірювання
 
├── Плани видів розрахунку     ← використовується РР
  CFG [label="Конфігурація K2 ERP", fillcolor="#cfd8dc"];
└── Регістри                   ◄── НОВИЙ РОЗДІЛ
 
    ├── Регістри відомостей
  C1 [label="Довідники", fillcolor="#eceff1"];
    │   └── КурсиВалют
  C2 [label="Документи", fillcolor="#eceff1"];
    │      ├── Вимірювання     → Валюта
  C3 [label="Плани рахунків", fillcolor="#eceff1"];
    │      ├── Ресурси         → Курс, Кратність
  C4 [label="Плани видів характеристик", fillcolor="#eceff1"];
    │      ├── Реквізити        →
   C5 [label="Плани видів розрахунку", fillcolor="#eceff1"];
    │      └── Форми            → ФормаСписку, ФормаЗапису
  REG [label="РЕГІСТРИ", fillcolor="#1976d2", fontcolor="white"];
    ├── Регістри накопичення
 
    │   └── ТовариНаСкладах
  CFG -> C1; CFG -> C2; CFG -> C3; CFG -> C4; CFG -> C5; CFG -> REG [penwidth=2, color="#1976d2"];
    │      ├── Вимірювання     → Номенклатура, Склад, Партія
 
    │      ├── Ресурси         → Кількість, Сума
  RI [label="Регістри відомостей", fillcolor="#e8f5e9"];
    │      ├── Реквізити       → Коментар
  RA [label="Регістри накопичення", fillcolor="#fff8e1"];
    │      └── Реєстратори     → [ПрихіднаНакладна, ВидатковаНакладна, ...]
  RB [label="Регістри бухгалтерії", fillcolor="#fce4ec"];
    ├── Регістри бухгалтерії
  RC [label="Регістри розрахунку", fillcolor="#ede7f6"];
    │   └── Госпрозрахунковий
  REG -> RI; REG -> RA; REG -> RB; REG -> RC;
    │      ├── Вимірювання     → Організація, Підрозділ(небаланс.)
 
    │      ├── Ресурси         → Сума(баланс.), Кількість(небаланс.), ВалютнаСума
   RI1 [label="КурсиВалют", fillcolor="#ffffff"];
    │      ├── Реквізити        → Зміст, № журналу
  RI -> RI1;
    │      └── Реєстратори      → [...]
  RI1d [label="Вимірювання: Валюта", shape=note, fillcolor="#fafafa", fontsize=8];
    └── Регістри розрахунку
  RI1r [label="Ресурси: Курс, Кратність", shape=note, fillcolor="#fafafa", fontsize=8];
        └── Нарахування
  RI1 -> RI1d; RI1 -> RI1r;
            ├── Вимірювання     → Співробітник(баз.), Підрозділ
 
            ├── Ресурси         → Результат, ВідпрацьованоДнів
  RA1 [label="ТовариНаСкладах", fillcolor="#ffffff"];
            ├── Реквізити        → Графік
  RA -> RA1;
            ├── Перерахунки      → ПерерахунокЗаБазою
   RA1d [label="Вимірювання:\lНоменклатура\lСклад\lПартія\l", shape=note, fillcolor="#fafafa", fontsize=8];
            └── Реєстратори      → [НарахуванняЗП]
  RA1r [label="Ресурси: Кількість, Сума", shape=note, fillcolor="#fafafa", fontsize=8];
</pre>
  RA1a [label="Реквізити: Коментар", shape=note, fillcolor="#fafafa", fontsize=8];
  RA1x [label="Реєстратори:\lПрихіднаНакладна\lВидатковаНакладна\l…\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RA1 -> RA1d; RA1 -> RA1r; RA1 -> RA1a; RA1 -> RA1x;
 
   RB1 [label="Госпрозрахунковий", fillcolor="#ffffff"];
  RB -> RB1;
  RB1d [label="Вимірювання:\lОрганізація (баланс.)\lПідрозділ (небаланс.)\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RB1r [label="Ресурси:\lСума (баланс.)\lКількість\lВалютнаСума\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RB1 -> RB1d; RB1 -> RB1r;
  RB1 -> C3 [style=dotted, color="#c2185b", arrowhead=vee, label="ПланРахунків", fontsize=7];
 
  RC1 [label="Нарахування", fillcolor="#ffffff"];
  RC -> RC1;
  RC1d [label="Вимірювання:\lСпівробітник (базове)\lПідрозділ\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RC1r [label="Ресурси:\lРезультат\lВідпрацьованоДнів\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RC1p [label="Перерахунки:\lПерерахунокЗаБазою\l", shape=note, fillcolor="#fafafa", fontsize=8];
  RC1 -> RC1d; RC1 -> RC1r; RC1 -> RC1p;
  RC1 -> C5 [style=dotted, color="#5e35b1", arrowhead=vee, label="ПВР", fontsize=7];
}
</graphviz>


== 6.2. Загальні властивості будь-якого регістру ==
== 6.2. Загальні властивості будь-якого регістру ==
Рядок 981: Рядок 1034:
'''ФТ-22.''' Якщо у ПВР для виду розрахунку A вказано B у складі «Витісняючі види розрахунку», то запис виду B скорочує фактичний період дії запису виду A на інтервал перетину.
'''ФТ-22.''' Якщо у ПВР для виду розрахунку A вказано B у складі «Витісняючі види розрахунку», то запис виду B скорочує фактичний період дії запису виду A на інтервал перетину.


<pre>
<uml>
Період реєстрації: Січень 2026.  Пріоритет витіснення: Лікарняний > Відпустка > Оклад
@startgantt
title Витіснення за періодом дії. Період реєстрації: січень 2026
caption Пріоритет витіснення: Лікарняний > Відпустка > Оклад
printscale daily
Project starts 2026-01-01


Заявлені періоди дії:
-- Заявлені періоди дії (rg_c_0040.act_begin / act_end) --
Оклад       01.01 ├══════════════════════════════════════════════┤ 31.01
[Оклад] as [O1] starts 2026-01-01 and ends 2026-01-31
Відпустка             10.01 ├════════════┤ 17.01
[Відпустка] as [V1] starts 2026-01-10 and ends 2026-01-17
Лікарняний                     14.01 ├════════════┤ 22.01
[Лікарняний] as [L1] starts 2026-01-14 and ends 2026-01-22
[O1] is colored in #BBDEFB
[V1] is colored in #FFE0B2
[L1] is colored in #F8BBD0


Фактичні періоди дії (rg_c_XXXX_ap):
-- Фактичні періоди дії після витіснення (rg_c_0040_ap) --
Оклад       01.01 ├═══════┤ 09.01           23.01 ├════════════┤ 31.01
[Оклад, інтервал 0] as [O2] starts 2026-01-01 and ends 2026-01-09
Відпустка             10.01 ├═══┤ 13.01
[Оклад, інтервал 1] as [O3] starts 2026-01-23 and ends 2026-01-31
Лікарняний                     14.01 ├════════════┤ 22.01
[Відпустка, інтервал 0] as [V2] starts 2026-01-10 and ends 2026-01-13
[Лікарняний, інтервал 0] as [L2] starts 2026-01-14 and ends 2026-01-22
[O2] is colored in #1976D2
[O3] is colored in #1976D2
[V2] is colored in #F57C00
[L2] is colored in #C2185B
@endgantt
</uml>


⇒ у таблиці фактичних періодів «Оклад» породжує ДВА інтервали (запис — один).
{{Note|'''Ключове спостереження.''' Один запис «Оклад» породжує '''два''' фактичні інтервали — саме тому <code>rg_c_0040_ap</code> має власний ключ <code>interval_no</code> і зв'язок 1:N із таблицею рухів (розділ 9.4). «Відпустка» скорочена з 17.01 до 13.01, бо лікарняний має вищий пріоритет.}}
</pre>


'''ФТ-23.''' Фактичні періоди дії матеріалізуються у службовій таблиці <code>rg_c_&lt;код&gt;_ap</code> під час запису набору записів.
'''ФТ-23.''' Фактичні періоди дії матеріалізуються у службовій таблиці <code>rg_c_&lt;код&gt;_ap</code> під час запису набору записів.
Рядок 1750: Рядок 1816:
== 8.8. Зведення: які таблиці породжує кожен тип регістру ==
== 8.8. Зведення: які таблиці породжує кожен тип регістру ==


<pre>
<graphviz>
РВ (незалежний)         → rg_i_<id>
digraph Tables {
РВ (підпорядкований)    →  rg_i_<id>
  rankdir=LR; bgcolor="transparent"; ranksep=0.6; nodesep=0.08;
  node [shape=box, style="filled,rounded", fontname="Helvetica", fontsize=9, height=0.26];
  edge [color="#9e9e9e", arrowhead=vee];
 
  RI  [label="РВ\n(незалежний або\nпідпорядкований)", fillcolor="#e8f5e9"];
  RAB [label="РН «Залишки»", fillcolor="#fff8e1"];
  RAT [label="РН «Обороти»", fillcolor="#fff8e1"];
  RB [label="РБ", fillcolor="#fce4ec"];
  RC  [label="РР", fillcolor="#ede7f6"];
 
  node [shape=cylinder, style=filled, fontname="Courier", fontsize=8, height=0.22];
 
  i1 [label="rg_i_<id>", fillcolor="#c8e6c9"];
  RI -> i1;
 
  a1 [label="rg_a_<id>", fillcolor="#ffecb3"];
  a2 [label="rg_a_<id>_tb", fillcolor="#ffe082"];
  a3 [label="rg_a_<id>_tt", fillcolor="#ffe082"];
  a4 [label="rg_a_<id>_opt", fillcolor="#fff3e0"];
  RAB -> a1; RAB -> a2 [label=" якщо підсумки залишків", fontsize=7];
  RAB -> a3 [label=" якщо підсумки оборотів", fontsize=7]; RAB -> a4;


РН (Залишки)            →  rg_a_<id>
  t1 [label="rg_a_<id>", fillcolor="#ffecb3"];
                            rg_a_<id>_tb        (якщо ДозволитиПідсумкиЗалишків)
  t2 [label="rg_a_<id>_tt", fillcolor="#ffe082"];
                            rg_a_<id>_tt        (якщо ДозволитиПідсумкиОборотів)
  t3 [label="rg_a_<id>_ag1..agN", fillcolor="#ffd54f"];
                            rg_a_<id>_opt
  t4 [label="rg_a_<id>_opt", fillcolor="#fff3e0"];
  RAT -> t1; RAT -> t2; RAT -> t3 [label=" агрегати", fontsize=7]; RAT -> t4;


РН (Обороти)            →  rg_a_<id>
  b1 [label="rg_b_<id>", fillcolor="#f8bbd0"];
                            rg_a_<id>_tt
  b2 [label="rg_b_<id>_tb0 .. _tbK", fillcolor="#f48fb1"];
                            rg_a_<id>_ag1..agN  (агрегати)
  b3 [label="rg_b_<id>_tt0 .. _ttK", fillcolor="#f48fb1"];
                            rg_a_<id>_opt
  b4 [label="rg_b_<id>_tc", fillcolor="#f48fb1"];
  b5 [label="rg_b_<id>_opt", fillcolor="#fce4ec"];
  RB -> b1; RB -> b2 [label=" K = МаксКількістьСубконто", fontsize=7]; RB -> b3; RB -> b4; RB -> b5;


РБ                      →  rg_b_<id>
  c1 [label="rg_c_<id>", fillcolor="#d1c4e9"];
                            rg_b_<id>_tb0 .. _tbK   (K = МаксКількістьСубконто)
  c2 [label="rg_c_<id>_ap", fillcolor="#b39ddb"];
                            rg_b_<id>_tt0 .. _ttK
   c3 [label="rg_c_<id>_rc1..rcM", fillcolor="#b39ddb"];
                            rg_b_<id>_tc
  RC -> c1; RC -> c2 [label=" фактичні періоди", fontsize=7]; RC -> c3 [label=" перерахунки", fontsize=7];
                            rg_b_<id>_opt


РР                      →  rg_c_<id>
  { rank=same; RI; RAB; RAT; RB; RC; }
                            rg_c_<id>_ap
}
                            rg_c_<id>_rc1 .. _rcM  (перерахунки)
</graphviz>
</pre>


Оцінка: для РБ з <code>МаксКількістьСубконто = 3</code> генерується '''10 фізичних таблиць''' на один регістр.
Оцінка: для РБ з <code>МаксКількістьСубконто = 3</code> генерується '''10 фізичних таблиць''' на один регістр.