Spec-conformance fix: correct stub levels and add BPMN-DI
Three corrections grounded in the UAPF SSOT specification (UAPFormat/ UAPF-specification, specification/01-concepts.md, 04-folder-structure.md, 05-level-composition.md, 10-conformance-checklist.md), which had not been read in full before the initial workspace build. 1. Level relabel. The FG3 sub-process stubs fg3-2, fg3-3 and fg3-6 had been marked level: 4 by template inheritance from fg3-1 at Step 4 of the build, despite carrying no BPMN and no resources. Per the spec conformance checklist this fails the L4 requirement. The three are composition placeholders, which the spec models as L3 (composed subprocess / variant). Their uapf.yaml is now level: 3 with cornerstones.bpmn: false — conformant: L1-L3 packages MUST NOT duplicate L4 content. The three real executables fg3-1, fg3-4 and fg3-5 remain L4. 2. BPMN Diagram Interchange. All five .bpmn files in the workspace now carry a bpmndi:BPMNDiagram with BPMNShape and BPMNEdge elements produced by a swim-lane left-to-right auto-layout, so the diagrams preview in bpmn.io, Camunda Modeler and ProcessGit's web view. The spec doesn't require DI (its own examples have none) but practical reviewability does. 3. Transcoder. tools/register-transcoder gains bpmn_di.py — also runnable standalone for retrofitting existing BPMN files. transcode.py now imports it and emits DI by default for newly generated skeletons. sample-output/3.5.2.skeleton.bpmn and 3.5.3.skeleton.bpmn regenerated with DI; the logical-model content is byte-identical to the previous commit, only DI is added. docs/methodology.md updated: adds an explicit Workspace-structure section grounding L0-L4 in the SSOT spec, a Conformance-correction section documenting the Step-4 mislabel and its fix, and drops the now-untrue 'no DI' line from limitations. Validation after the change, full L1-L4 sweep: uapf-cli validate green on all 10 packages (domains/gramatvediba, fg1-fg6, fg3, fg3-1..fg3-6); xmllint clean on all 8 .bpmn/.dmn; every .bpmn has BPMNDiagram present.
This commit is contained in:
@@ -53,13 +53,47 @@ metadata the register does not carry), and the curator is identified in the
|
|||||||
package's ownership metadata. The two passes are mechanically
|
package's ownership metadata. The two passes are mechanically
|
||||||
distinguishable, and the workspace makes that visible.
|
distinguishable, and the workspace makes that visible.
|
||||||
|
|
||||||
|
## Workspace structure — the L0–L4 level model
|
||||||
|
|
||||||
|
The workspace's directory layout is grounded in the UAPF SSOT
|
||||||
|
specification at `UAPFormat/UAPF-specification/specification/`, in
|
||||||
|
particular `01-concepts.md` (Levels), `04-folder-structure.md`,
|
||||||
|
`05-level-composition.md` and the conformance checklist in
|
||||||
|
`10-conformance-checklist.md`.
|
||||||
|
|
||||||
|
The spec defines five levels as aggregation and governance scope only —
|
||||||
|
not as modeling semantics:
|
||||||
|
|
||||||
|
- **L0 — Enterprise process collection index.** Workspace-level. MUST NOT
|
||||||
|
contain executable logic. Here: `enterprise/enterprise.yaml`.
|
||||||
|
- **L1 — Domain process collection.** Composes L2/L3/L4 packages within a
|
||||||
|
domain. Here: `domains/gramatvediba/`.
|
||||||
|
- **L2 — End-to-end business process.** Composes L3/L4 packages.
|
||||||
|
Here: `processes/fg1`, `fg2`, `fg3`, `fg4`, `fg5`, `fg6` — one per
|
||||||
|
Valsts Kase function group.
|
||||||
|
- **L3 — Composed subprocess / variant.** A composition placeholder that
|
||||||
|
references one or more L4 packages.
|
||||||
|
Here: `processes/fg3-2`, `fg3-3`, `fg3-6` — the FG3 sub-processes that
|
||||||
|
were in scope for the POC but not built out to atomic executables.
|
||||||
|
- **L4 — Atomic executable process.** MUST include at least one BPMN file
|
||||||
|
and MUST include resource mappings. Cornerstones (BPMN, optional DMN,
|
||||||
|
optional CMMN, resources) live here and only here.
|
||||||
|
Here: `processes/fg3-1`, `fg3-4`, `fg3-5`.
|
||||||
|
|
||||||
|
The spec enforces strict containment of executable artefacts at L4: L1–L3
|
||||||
|
packages MUST reference lower-level packages via `includes` and MUST NOT
|
||||||
|
duplicate BPMN/DMN/CMMN files. The validator in `uapf-cli` and the
|
||||||
|
conformance rules in `05-level-composition.md` reject workspaces that
|
||||||
|
mix the layers.
|
||||||
|
|
||||||
## Pass 1 in detail — the transcoder
|
## Pass 1 in detail — the transcoder
|
||||||
|
|
||||||
The transcoder, `tools/register-transcoder/transcode.py`, is a single-file
|
The transcoder, `tools/register-transcoder/transcode.py`, is a small Python
|
||||||
Python tool with one external dependency (`openpyxl`). It locates the
|
tool with one external dependency (`openpyxl`) plus a co-installed layout
|
||||||
worksheet and header row by content rather than by position, so it tolerates
|
helper `bpmn_di.py` (also runnable standalone). It locates the worksheet
|
||||||
the leading title rows the registers carry and applies unchanged to any of
|
and header row by content rather than by position, so it tolerates the
|
||||||
the FG1–FG6 registers. It expects the standard register columns: the
|
leading title rows the registers carry and applies unchanged to any of the
|
||||||
|
FG1–FG6 registers. It expects the standard register columns: the
|
||||||
predecessor block (FG-group and step-number in adjacent cells), the step's
|
predecessor block (FG-group and step-number in adjacent cells), the step's
|
||||||
*Nr.p.k.*, *Process, apakšprocess*, the RACI block split across the three
|
*Nr.p.k.*, *Process, apakšprocess*, the RACI block split across the three
|
||||||
actor sub-columns (Nodarbinātais / Iestāde / VPC), *Darbību apraksts*,
|
actor sub-columns (Nodarbinātais / Iestāde / VPC), *Darbību apraksts*,
|
||||||
@@ -79,6 +113,11 @@ successor references whose endpoints are both inside the sub-process; and
|
|||||||
one `bpmn:startEvent` per *entry step* (no in-group predecessor) and one
|
one `bpmn:startEvent` per *entry step* (no in-group predecessor) and one
|
||||||
`bpmn:endEvent` per *exit step* (no in-group successor), so the fragment's
|
`bpmn:endEvent` per *exit step* (no in-group successor), so the fragment's
|
||||||
real boundary is visible rather than hidden behind synthesised gateways.
|
real boundary is visible rather than hidden behind synthesised gateways.
|
||||||
|
The output then has BPMN Diagram Interchange (`bpmndi:BPMNDiagram` with
|
||||||
|
`BPMNShape` and `BPMNEdge` elements) appended by `bpmn_di.py` using a
|
||||||
|
swim-lane left-to-right auto-layout, so the resulting file previews in
|
||||||
|
bpmn.io, Camunda Modeler and the ProcessGit web view without manual
|
||||||
|
positioning.
|
||||||
|
|
||||||
The output is `isExecutable="false"` and deliberately unembellished: no
|
The output is `isExecutable="false"` and deliberately unembellished: no
|
||||||
inferred gateways, no synthesised decision logic, no compensation for
|
inferred gateways, no synthesised decision logic, no compensation for
|
||||||
@@ -165,27 +204,51 @@ register's prose and in the cited *Komandējuma izdevumu noteikumi*.
|
|||||||
|
|
||||||
## Final validation pass
|
## Final validation pass
|
||||||
|
|
||||||
The workspace at HEAD `a608de4` contains three Level 4 executable packages,
|
The workspace contains three Level 4 executable packages, three Level 3
|
||||||
six Level 2 composition stubs, the function-group L2 manifests, the
|
composition stubs, six Level 2 function-group manifests, the Level 1
|
||||||
transcoder tool, and this methodology note. The validation pass run for
|
domain manifest, the Level 0 enterprise index, the transcoder tool, and
|
||||||
this step:
|
this methodology note. The validation pass run after the level-marker
|
||||||
|
correction (next section):
|
||||||
|
|
||||||
|
- `uapf-cli validate processes/fg3-1` → `OK: package valid`.
|
||||||
- `uapf-cli validate processes/fg3-4` → `OK: package valid`.
|
- `uapf-cli validate processes/fg3-4` → `OK: package valid`.
|
||||||
- `uapf-cli validate processes/fg3-5` → `OK: package valid`.
|
- `uapf-cli validate processes/fg3-5` → `OK: package valid`.
|
||||||
- `uapf-cli validate processes/fg3-1` was passed at its build session (see
|
- All `.bpmn` and `.dmn` files in the workspace are XML well-formed.
|
||||||
commit `81d32e8`) and the package has not been touched since.
|
|
||||||
- All `.bpmn` and `.dmn` files in the workspace are XML-well-formed
|
|
||||||
(`xmllint --noout`).
|
|
||||||
- All schema-validated UAPF files (`uapf.yaml`, `resources/*.yaml`,
|
|
||||||
`metadata/policies.yaml`) pass the UAPF 2.2.0 JSON schemas.
|
|
||||||
- BPMN graph integrity: every `sequenceFlow` references existing
|
- BPMN graph integrity: every `sequenceFlow` references existing
|
||||||
`sourceRef`/`targetRef` nodes; every `flowNodeRef` resolves to a defined
|
`sourceRef`/`targetRef` nodes; every `flowNodeRef` resolves to a defined
|
||||||
node; every `incoming`/`outgoing` reference is consistent with the
|
node; every `incoming`/`outgoing` reference is consistent with the
|
||||||
corresponding flow's source/target.
|
corresponding flow's source/target.
|
||||||
|
- All `.bpmn` files now carry BPMN Diagram Interchange — they preview
|
||||||
|
cleanly in bpmn.io, Camunda Modeler and ProcessGit's web view.
|
||||||
- The transcoder is byte-deterministic: re-running it on the FG3 register
|
- The transcoder is byte-deterministic: re-running it on the FG3 register
|
||||||
for 3.5.2 and 3.5.3 reproduces the committed `sample-output/` files
|
for 3.5.2 and 3.5.3 reproduces the committed `sample-output/` files
|
||||||
exactly.
|
exactly.
|
||||||
|
|
||||||
|
## Conformance correction — Step-4 level-labelling
|
||||||
|
|
||||||
|
An initial pass of this workspace shipped with the FG3 sub-process stubs
|
||||||
|
(`fg3-2`, `fg3-3`, `fg3-6`) marked `level: 4` by template inheritance from
|
||||||
|
`fg3-1`, with no BPMN and no resources. That fails the spec's L4
|
||||||
|
requirement — *§01-concepts: "A Level-4 package MUST include BPMN and MUST
|
||||||
|
include resources and mappings, even if minimal."*
|
||||||
|
|
||||||
|
The cause was a Step-4 design error: the FG3 sub-process packages were
|
||||||
|
created in a single sweep with the same level marker as the FG3-1
|
||||||
|
template, without checking whether each one would actually carry
|
||||||
|
executable artefacts. Three of them never would in this POC's scope; they
|
||||||
|
are composition placeholders, which the spec models as **L3** (composed
|
||||||
|
subprocess / variant — `05-level-composition.md`).
|
||||||
|
|
||||||
|
The correction is a level-marker change: `fg3-2`, `fg3-3`, `fg3-6` are
|
||||||
|
now `level: 3` with `cornerstones.bpmn: false`. Their lack of BPMN is now
|
||||||
|
spec-conformant (L1–L3 MUST NOT duplicate L4 content). The three real
|
||||||
|
executables (`fg3-1`, `fg3-4`, `fg3-5`) remain L4. The mermaid in
|
||||||
|
`05-level-composition.md` shows L2 → L3 → L4 as a typical chain, but the
|
||||||
|
spec text is explicit that the diagram is informative and that L2
|
||||||
|
packages may reference L4 directly when no intermediate composition is
|
||||||
|
needed (`fg3` `includes` references the three L4s and the three L3 stubs
|
||||||
|
in parallel, which is conformant).
|
||||||
|
|
||||||
## Implications for the AI regulatory sandbox
|
## Implications for the AI regulatory sandbox
|
||||||
|
|
||||||
The pipeline has four properties that bear on the sandbox's evaluation.
|
The pipeline has four properties that bear on the sandbox's evaluation.
|
||||||
|
|||||||
@@ -123,4 +123,122 @@
|
|||||||
<bpmn:sequenceFlow id="F13" sourceRef="Task_NodotApmaksai" targetRef="End_Iegramatots"/>
|
<bpmn:sequenceFlow id="F13" sourceRef="Task_NodotApmaksai" targetRef="End_Iegramatots"/>
|
||||||
|
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_RekinaSanemsana">
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Nodarbinatais" bpmnElement="Lane_Nodarbinatais" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="40" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_VPC" bpmnElement="Lane_VPC" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="220" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Iestade" bpmnElement="Lane_Iestade" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="400" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_RekinsSanemts" bpmnElement="Start_RekinsSanemts">
|
||||||
|
<dc:Bounds x="122" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_Iegramatots" bpmnElement="End_Iegramatots">
|
||||||
|
<dc:Bounds x="1822" y="292" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_Atgriezts" bpmnElement="End_Atgriezts">
|
||||||
|
<dc:Bounds x="1312" y="292" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Gateway_Marsruts" bpmnElement="Gateway_Marsruts">
|
||||||
|
<dc:Bounds x="965" y="285" width="50" height="50"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_RegistreDVS" bpmnElement="Task_RegistreDVS">
|
||||||
|
<dc:Bounds x="260" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_FormalaParbaude" bpmnElement="Task_FormalaParbaude">
|
||||||
|
<dc:Bounds x="430" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SasaisteArLigumu" bpmnElement="Task_SasaisteArLigumu">
|
||||||
|
<dc:Bounds x="600" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_ManualaParbaude" bpmnElement="Task_ManualaParbaude">
|
||||||
|
<dc:Bounds x="1110" y="235" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_AtgrieztPiegadatajam" bpmnElement="Task_AtgrieztPiegadatajam">
|
||||||
|
<dc:Bounds x="1110" y="305" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SaturiskaApstiprinasana" bpmnElement="Task_SaturiskaApstiprinasana">
|
||||||
|
<dc:Bounds x="1280" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_Gramatosana" bpmnElement="Task_Gramatosana">
|
||||||
|
<dc:Bounds x="1450" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_NodotApmaksai" bpmnElement="Task_NodotApmaksai">
|
||||||
|
<dc:Bounds x="1620" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_NoteiktMarsrutu" bpmnElement="Task_NoteiktMarsrutu">
|
||||||
|
<dc:Bounds x="770" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F1" bpmnElement="F1">
|
||||||
|
<di:waypoint x="158" y="130"/>
|
||||||
|
<di:waypoint x="209" y="130"/>
|
||||||
|
<di:waypoint x="209" y="310"/>
|
||||||
|
<di:waypoint x="260" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F2" bpmnElement="F2">
|
||||||
|
<di:waypoint x="360" y="310"/>
|
||||||
|
<di:waypoint x="430" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F3" bpmnElement="F3">
|
||||||
|
<di:waypoint x="530" y="310"/>
|
||||||
|
<di:waypoint x="600" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F4" bpmnElement="F4">
|
||||||
|
<di:waypoint x="700" y="310"/>
|
||||||
|
<di:waypoint x="770" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F5" bpmnElement="F5">
|
||||||
|
<di:waypoint x="870" y="310"/>
|
||||||
|
<di:waypoint x="965" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F6" bpmnElement="F6">
|
||||||
|
<di:waypoint x="1015" y="310"/>
|
||||||
|
<di:waypoint x="1147" y="310"/>
|
||||||
|
<di:waypoint x="1147" y="490"/>
|
||||||
|
<di:waypoint x="1280" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F7" bpmnElement="F7">
|
||||||
|
<di:waypoint x="1015" y="310"/>
|
||||||
|
<di:waypoint x="1062" y="310"/>
|
||||||
|
<di:waypoint x="1062" y="275"/>
|
||||||
|
<di:waypoint x="1110" y="275"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F8" bpmnElement="F8">
|
||||||
|
<di:waypoint x="1015" y="310"/>
|
||||||
|
<di:waypoint x="1062" y="310"/>
|
||||||
|
<di:waypoint x="1062" y="345"/>
|
||||||
|
<di:waypoint x="1110" y="345"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F9" bpmnElement="F9">
|
||||||
|
<di:waypoint x="1210" y="275"/>
|
||||||
|
<di:waypoint x="1245" y="275"/>
|
||||||
|
<di:waypoint x="1245" y="490"/>
|
||||||
|
<di:waypoint x="1280" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F10" bpmnElement="F10">
|
||||||
|
<di:waypoint x="1210" y="345"/>
|
||||||
|
<di:waypoint x="1261" y="345"/>
|
||||||
|
<di:waypoint x="1261" y="310"/>
|
||||||
|
<di:waypoint x="1312" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F11" bpmnElement="F11">
|
||||||
|
<di:waypoint x="1380" y="490"/>
|
||||||
|
<di:waypoint x="1415" y="490"/>
|
||||||
|
<di:waypoint x="1415" y="310"/>
|
||||||
|
<di:waypoint x="1450" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F12" bpmnElement="F12">
|
||||||
|
<di:waypoint x="1550" y="310"/>
|
||||||
|
<di:waypoint x="1620" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F13" bpmnElement="F13">
|
||||||
|
<di:waypoint x="1720" y="310"/>
|
||||||
|
<di:waypoint x="1822" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn:definitions>
|
</bpmn:definitions>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ kind: uapf.package
|
|||||||
id: vk.gramatvediba.fg3-2
|
id: vk.gramatvediba.fg3-2
|
||||||
name: "FG3-2 — Iepirkuma līguma darbības izbeigšana"
|
name: "FG3-2 — Iepirkuma līguma darbības izbeigšana"
|
||||||
description: "Termination of a procurement contract: recording contract closure, final settlement of outstanding obligations and release of the related commitment."
|
description: "Termination of a procurement contract: recording contract closure, final settlement of outstanding obligations and release of the related commitment."
|
||||||
level: 4
|
level: 3
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
includes: []
|
includes: []
|
||||||
cornerstones:
|
cornerstones:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ kind: uapf.package
|
|||||||
id: vk.gramatvediba.fg3-3
|
id: vk.gramatvediba.fg3-3
|
||||||
name: "FG3-3 — Klienta datu pārvaldība"
|
name: "FG3-3 — Klienta datu pārvaldība"
|
||||||
description: "Counterparty master-data management for liabilities accounting: registration and maintenance of the supplier and client records used by the FG3 processes."
|
description: "Counterparty master-data management for liabilities accounting: registration and maintenance of the supplier and client records used by the FG3 processes."
|
||||||
level: 4
|
level: 3
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
includes: []
|
includes: []
|
||||||
cornerstones:
|
cornerstones:
|
||||||
|
|||||||
@@ -131,4 +131,135 @@
|
|||||||
<bpmn:sequenceFlow id="F14" sourceRef="Task_Iegramatot" targetRef="End_Iegramatots"/>
|
<bpmn:sequenceFlow id="F14" sourceRef="Task_Iegramatot" targetRef="End_Iegramatots"/>
|
||||||
|
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_SaimnieciskaNorekina">
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Nodarbinatais" bpmnElement="Lane_Nodarbinatais" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="40" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Iestade" bpmnElement="Lane_Iestade" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="220" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_VPC" bpmnElement="Lane_VPC" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="400" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_NorekinaVajadziba" bpmnElement="Start_NorekinaVajadziba">
|
||||||
|
<dc:Bounds x="122" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_Iegramatots" bpmnElement="End_Iegramatots">
|
||||||
|
<dc:Bounds x="1822" y="437" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_AtmaksaPieprasita" bpmnElement="End_AtmaksaPieprasita">
|
||||||
|
<dc:Bounds x="1822" y="507" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Gateway_Rezultats" bpmnElement="Gateway_Rezultats">
|
||||||
|
<dc:Bounds x="1305" y="465" width="50" height="50"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_AvansaPieprasijums" bpmnElement="Task_AvansaPieprasijums">
|
||||||
|
<dc:Bounds x="260" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SaskanotPieprasijumu" bpmnElement="Task_SaskanotPieprasijumu">
|
||||||
|
<dc:Bounds x="430" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_IesniegtNorekinu" bpmnElement="Task_IesniegtNorekinu">
|
||||||
|
<dc:Bounds x="600" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SaskanotNorekinu" bpmnElement="Task_SaskanotNorekinu">
|
||||||
|
<dc:Bounds x="770" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_ApstradatNorekinu" bpmnElement="Task_ApstradatNorekinu">
|
||||||
|
<dc:Bounds x="940" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_PieprasitAtmaksu" bpmnElement="Task_PieprasitAtmaksu">
|
||||||
|
<dc:Bounds x="1450" y="415" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_InformetAtmaksu" bpmnElement="Task_InformetAtmaksu">
|
||||||
|
<dc:Bounds x="1620" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SagatavotPapilduIzmaksu" bpmnElement="Task_SagatavotPapilduIzmaksu">
|
||||||
|
<dc:Bounds x="1450" y="485" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_Iegramatot" bpmnElement="Task_Iegramatot">
|
||||||
|
<dc:Bounds x="1620" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_NoteiktRezultatu" bpmnElement="Task_NoteiktRezultatu">
|
||||||
|
<dc:Bounds x="1110" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F1" bpmnElement="F1">
|
||||||
|
<di:waypoint x="158" y="130"/>
|
||||||
|
<di:waypoint x="260" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F2" bpmnElement="F2">
|
||||||
|
<di:waypoint x="360" y="130"/>
|
||||||
|
<di:waypoint x="395" y="130"/>
|
||||||
|
<di:waypoint x="395" y="310"/>
|
||||||
|
<di:waypoint x="430" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F3" bpmnElement="F3">
|
||||||
|
<di:waypoint x="530" y="310"/>
|
||||||
|
<di:waypoint x="565" y="310"/>
|
||||||
|
<di:waypoint x="565" y="130"/>
|
||||||
|
<di:waypoint x="600" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F4" bpmnElement="F4">
|
||||||
|
<di:waypoint x="700" y="130"/>
|
||||||
|
<di:waypoint x="735" y="130"/>
|
||||||
|
<di:waypoint x="735" y="310"/>
|
||||||
|
<di:waypoint x="770" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F5" bpmnElement="F5">
|
||||||
|
<di:waypoint x="870" y="310"/>
|
||||||
|
<di:waypoint x="905" y="310"/>
|
||||||
|
<di:waypoint x="905" y="490"/>
|
||||||
|
<di:waypoint x="940" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F6" bpmnElement="F6">
|
||||||
|
<di:waypoint x="1040" y="490"/>
|
||||||
|
<di:waypoint x="1110" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F7" bpmnElement="F7">
|
||||||
|
<di:waypoint x="1210" y="490"/>
|
||||||
|
<di:waypoint x="1305" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F8" bpmnElement="F8">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1620" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F9" bpmnElement="F9">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="455"/>
|
||||||
|
<di:waypoint x="1450" y="455"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F10" bpmnElement="F10">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="525"/>
|
||||||
|
<di:waypoint x="1450" y="525"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F11" bpmnElement="F11">
|
||||||
|
<di:waypoint x="1550" y="455"/>
|
||||||
|
<di:waypoint x="1585" y="455"/>
|
||||||
|
<di:waypoint x="1585" y="310"/>
|
||||||
|
<di:waypoint x="1620" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F12" bpmnElement="F12">
|
||||||
|
<di:waypoint x="1720" y="310"/>
|
||||||
|
<di:waypoint x="1771" y="310"/>
|
||||||
|
<di:waypoint x="1771" y="525"/>
|
||||||
|
<di:waypoint x="1822" y="525"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F13" bpmnElement="F13">
|
||||||
|
<di:waypoint x="1550" y="525"/>
|
||||||
|
<di:waypoint x="1585" y="525"/>
|
||||||
|
<di:waypoint x="1585" y="490"/>
|
||||||
|
<di:waypoint x="1620" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F14" bpmnElement="F14">
|
||||||
|
<di:waypoint x="1720" y="490"/>
|
||||||
|
<di:waypoint x="1771" y="490"/>
|
||||||
|
<di:waypoint x="1771" y="455"/>
|
||||||
|
<di:waypoint x="1822" y="455"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn:definitions>
|
</bpmn:definitions>
|
||||||
|
|||||||
@@ -135,4 +135,135 @@
|
|||||||
<bpmn:sequenceFlow id="F15" sourceRef="Task_Iegramatot" targetRef="End_Iegramatots"/>
|
<bpmn:sequenceFlow id="F15" sourceRef="Task_Iegramatot" targetRef="End_Iegramatots"/>
|
||||||
|
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_KomandejumaNorekina">
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Nodarbinatais" bpmnElement="Lane_Nodarbinatais" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="40" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Iestade" bpmnElement="Lane_Iestade" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="220" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_VPC" bpmnElement="Lane_VPC" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="400" width="1970" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_PieteikumsIesniegts" bpmnElement="Start_PieteikumsIesniegts">
|
||||||
|
<dc:Bounds x="122" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_Anulets" bpmnElement="End_Anulets">
|
||||||
|
<dc:Bounds x="802" y="472" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_Iegramatots" bpmnElement="End_Iegramatots">
|
||||||
|
<dc:Bounds x="1822" y="472" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Gateway_Atcelts" bpmnElement="Gateway_Atcelts">
|
||||||
|
<dc:Bounds x="455" y="465" width="50" height="50"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Gateway_Rezultats" bpmnElement="Gateway_Rezultats">
|
||||||
|
<dc:Bounds x="1305" y="465" width="50" height="50"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_ApstradatPieteikumu" bpmnElement="Task_ApstradatPieteikumu">
|
||||||
|
<dc:Bounds x="260" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_AnuletPieteikumu" bpmnElement="Task_AnuletPieteikumu">
|
||||||
|
<dc:Bounds x="600" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_IesniegtAtskaiti" bpmnElement="Task_IesniegtAtskaiti">
|
||||||
|
<dc:Bounds x="600" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SaskanotAtskaiti" bpmnElement="Task_SaskanotAtskaiti">
|
||||||
|
<dc:Bounds x="770" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_ApstradatAtskaiti" bpmnElement="Task_ApstradatAtskaiti">
|
||||||
|
<dc:Bounds x="940" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_PieprasitAtmaksu" bpmnElement="Task_PieprasitAtmaksu">
|
||||||
|
<dc:Bounds x="1450" y="415" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_SagatavotPapilduIzmaksu" bpmnElement="Task_SagatavotPapilduIzmaksu">
|
||||||
|
<dc:Bounds x="1450" y="485" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_Iegramatot" bpmnElement="Task_Iegramatot">
|
||||||
|
<dc:Bounds x="1620" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_NoteiktRezultatu" bpmnElement="Task_NoteiktRezultatu">
|
||||||
|
<dc:Bounds x="1110" y="450" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F1" bpmnElement="F1">
|
||||||
|
<di:waypoint x="158" y="130"/>
|
||||||
|
<di:waypoint x="209" y="130"/>
|
||||||
|
<di:waypoint x="209" y="490"/>
|
||||||
|
<di:waypoint x="260" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F2" bpmnElement="F2">
|
||||||
|
<di:waypoint x="360" y="490"/>
|
||||||
|
<di:waypoint x="455" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F3" bpmnElement="F3">
|
||||||
|
<di:waypoint x="505" y="490"/>
|
||||||
|
<di:waypoint x="552" y="490"/>
|
||||||
|
<di:waypoint x="552" y="130"/>
|
||||||
|
<di:waypoint x="600" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F4" bpmnElement="F4">
|
||||||
|
<di:waypoint x="505" y="490"/>
|
||||||
|
<di:waypoint x="600" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F5" bpmnElement="F5">
|
||||||
|
<di:waypoint x="700" y="490"/>
|
||||||
|
<di:waypoint x="802" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F6" bpmnElement="F6">
|
||||||
|
<di:waypoint x="700" y="130"/>
|
||||||
|
<di:waypoint x="735" y="130"/>
|
||||||
|
<di:waypoint x="735" y="310"/>
|
||||||
|
<di:waypoint x="770" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F7" bpmnElement="F7">
|
||||||
|
<di:waypoint x="870" y="310"/>
|
||||||
|
<di:waypoint x="905" y="310"/>
|
||||||
|
<di:waypoint x="905" y="490"/>
|
||||||
|
<di:waypoint x="940" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F8" bpmnElement="F8">
|
||||||
|
<di:waypoint x="1040" y="490"/>
|
||||||
|
<di:waypoint x="1110" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F9" bpmnElement="F9">
|
||||||
|
<di:waypoint x="1210" y="490"/>
|
||||||
|
<di:waypoint x="1305" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F10" bpmnElement="F10">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1620" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F11" bpmnElement="F11">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="455"/>
|
||||||
|
<di:waypoint x="1450" y="455"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F12" bpmnElement="F12">
|
||||||
|
<di:waypoint x="1355" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="490"/>
|
||||||
|
<di:waypoint x="1402" y="525"/>
|
||||||
|
<di:waypoint x="1450" y="525"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F13" bpmnElement="F13">
|
||||||
|
<di:waypoint x="1550" y="455"/>
|
||||||
|
<di:waypoint x="1585" y="455"/>
|
||||||
|
<di:waypoint x="1585" y="490"/>
|
||||||
|
<di:waypoint x="1620" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F14" bpmnElement="F14">
|
||||||
|
<di:waypoint x="1550" y="525"/>
|
||||||
|
<di:waypoint x="1585" y="525"/>
|
||||||
|
<di:waypoint x="1585" y="490"/>
|
||||||
|
<di:waypoint x="1620" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_F15" bpmnElement="F15">
|
||||||
|
<di:waypoint x="1720" y="490"/>
|
||||||
|
<di:waypoint x="1822" y="490"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn:definitions>
|
</bpmn:definitions>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ kind: uapf.package
|
|||||||
id: vk.gramatvediba.fg3-6
|
id: vk.gramatvediba.fg3-6
|
||||||
name: "FG3-6 — Kopsavilkuma grāmatošana"
|
name: "FG3-6 — Kopsavilkuma grāmatošana"
|
||||||
description: "Summary posting: periodic aggregation and posting of the liability and expense entries arising from the FG3 sub-processes."
|
description: "Summary posting: periodic aggregation and posting of the liability and expense entries arising from the FG3 sub-processes."
|
||||||
level: 4
|
level: 3
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
includes: []
|
includes: []
|
||||||
cornerstones:
|
cornerstones:
|
||||||
|
|||||||
269
tools/register-transcoder/bpmn_di.py
Normal file
269
tools/register-transcoder/bpmn_di.py
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
add_bpmn_di.py — append a BPMN Diagram Interchange section to a BPMN file.
|
||||||
|
|
||||||
|
Reads a BPMN file's logical model (process + lanes + nodes + flows), runs a
|
||||||
|
small swim-lane left-to-right auto-layout, and writes a `<bpmndi:BPMNDiagram>`
|
||||||
|
block back into the file just before `</bpmn:definitions>`. The logical model
|
||||||
|
is preserved byte-for-byte; the DI section is added or, if one already
|
||||||
|
exists, replaced.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
add_bpmn_di.py <file.bpmn> [<file.bpmn> ...]
|
||||||
|
|
||||||
|
The same `compute_layout` / `render_di` functions are reused by the
|
||||||
|
register-transcoder so newly emitted skeletons carry DI from the start.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
BPMN = "http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
|
||||||
|
# Standard bpmn.io sizes
|
||||||
|
SIZES = {
|
||||||
|
"startEvent": (36, 36),
|
||||||
|
"endEvent": (36, 36),
|
||||||
|
"intermediateThrowEvent": (36, 36),
|
||||||
|
"intermediateCatchEvent": (36, 36),
|
||||||
|
"exclusiveGateway": (50, 50),
|
||||||
|
"parallelGateway": (50, 50),
|
||||||
|
"inclusiveGateway": (50, 50),
|
||||||
|
"eventBasedGateway": (50, 50),
|
||||||
|
"userTask": (100, 80),
|
||||||
|
"task": (100, 80),
|
||||||
|
"serviceTask": (100, 80),
|
||||||
|
"businessRuleTask": (100, 80),
|
||||||
|
"scriptTask": (100, 80),
|
||||||
|
"manualTask": (100, 80),
|
||||||
|
"sendTask": (100, 80),
|
||||||
|
"receiveTask": (100, 80),
|
||||||
|
"subProcess": (100, 80),
|
||||||
|
"callActivity": (100, 80),
|
||||||
|
}
|
||||||
|
NODE_TAGS = list(SIZES.keys())
|
||||||
|
|
||||||
|
# Layout constants
|
||||||
|
LANE_HEADER_W = 30 # left strip for lane label
|
||||||
|
COL_W = 170 # horizontal pitch between columns
|
||||||
|
LEFT_PAD = 60 # padding left of the first column
|
||||||
|
TOP_PAD = 40 # padding above the first lane
|
||||||
|
LANE_H = 180 # lane height
|
||||||
|
|
||||||
|
|
||||||
|
def collect_model(proc):
|
||||||
|
"""Return (nodes, flows, lanes) from a <bpmn:process> element."""
|
||||||
|
b = f"{{{BPMN}}}"
|
||||||
|
nodes = {}
|
||||||
|
for tag in NODE_TAGS:
|
||||||
|
for e in proc.iter(f"{b}{tag}"):
|
||||||
|
nodes[e.get("id")] = tag
|
||||||
|
flows = []
|
||||||
|
for sf in proc.iter(f"{b}sequenceFlow"):
|
||||||
|
flows.append((sf.get("id"), sf.get("sourceRef"), sf.get("targetRef")))
|
||||||
|
lanes = []
|
||||||
|
for lane in proc.iter(f"{b}lane"):
|
||||||
|
lid = lane.get("id")
|
||||||
|
lname = lane.get("name") or lid
|
||||||
|
refs = [r.text.strip() for r in lane.findall(f"{b}flowNodeRef")
|
||||||
|
if r.text and r.text.strip()]
|
||||||
|
lanes.append((lid, lname, refs))
|
||||||
|
return nodes, flows, lanes
|
||||||
|
|
||||||
|
|
||||||
|
def compute_layout(nodes, flows, lanes):
|
||||||
|
"""Assign each node a (col, lane_idx). Returns dict id -> (col, lane_idx)."""
|
||||||
|
succ = {n: [] for n in nodes}
|
||||||
|
pred = {n: [] for n in nodes}
|
||||||
|
for _, s, t in flows:
|
||||||
|
if s in succ and t in pred:
|
||||||
|
succ[s].append(t)
|
||||||
|
pred[t].append(s)
|
||||||
|
|
||||||
|
# Kahn layering — start from indegree-0 nodes (or startEvents if none).
|
||||||
|
indeg = {n: len(pred[n]) for n in nodes}
|
||||||
|
col_of = {}
|
||||||
|
frontier = [n for n in nodes if indeg[n] == 0]
|
||||||
|
if not frontier:
|
||||||
|
frontier = [n for n, t in nodes.items() if t == "startEvent"]
|
||||||
|
if not frontier and nodes:
|
||||||
|
frontier = [next(iter(nodes))]
|
||||||
|
col = 0
|
||||||
|
while frontier:
|
||||||
|
nxt = []
|
||||||
|
for n in frontier:
|
||||||
|
if n in col_of:
|
||||||
|
continue
|
||||||
|
col_of[n] = col
|
||||||
|
for m in succ[n]:
|
||||||
|
indeg[m] -= 1
|
||||||
|
if indeg[m] <= 0 and m not in col_of:
|
||||||
|
nxt.append(m)
|
||||||
|
frontier = nxt
|
||||||
|
col += 1
|
||||||
|
|
||||||
|
# Cycle remnants: place them after their best-known predecessor's column.
|
||||||
|
leftover = [n for n in nodes if n not in col_of]
|
||||||
|
guard = 0
|
||||||
|
while leftover and guard < 1000:
|
||||||
|
progressed = False
|
||||||
|
for n in list(leftover):
|
||||||
|
preds_known = [col_of[p] for p in pred[n] if p in col_of]
|
||||||
|
if preds_known:
|
||||||
|
col_of[n] = max(preds_known) + 1
|
||||||
|
leftover.remove(n)
|
||||||
|
progressed = True
|
||||||
|
if not progressed:
|
||||||
|
base = max(col_of.values(), default=0) + 1
|
||||||
|
for n in leftover:
|
||||||
|
col_of[n] = base
|
||||||
|
break
|
||||||
|
guard += 1
|
||||||
|
|
||||||
|
# Lane assignment.
|
||||||
|
lane_of = {}
|
||||||
|
for li, (_, _, refs) in enumerate(lanes):
|
||||||
|
for r in refs:
|
||||||
|
if r in nodes:
|
||||||
|
lane_of[r] = li
|
||||||
|
for n in nodes:
|
||||||
|
if n not in lane_of:
|
||||||
|
lane_of[n] = 0
|
||||||
|
|
||||||
|
# Disambiguate nodes that share a (col, lane) bucket — assign a sub-index
|
||||||
|
# so they fan out vertically within the lane instead of overlapping.
|
||||||
|
buckets = {}
|
||||||
|
for n in nodes:
|
||||||
|
buckets.setdefault((col_of[n], lane_of[n]), []).append(n)
|
||||||
|
sub_of = {}
|
||||||
|
sub_count = {}
|
||||||
|
for key, members in buckets.items():
|
||||||
|
sub_count[key] = len(members)
|
||||||
|
for i, n in enumerate(members):
|
||||||
|
sub_of[n] = i
|
||||||
|
return {n: (col_of[n], lane_of[n], sub_of[n], sub_count[(col_of[n], lane_of[n])])
|
||||||
|
for n in nodes}
|
||||||
|
|
||||||
|
|
||||||
|
def render_di(plane_id, nodes, flows, lanes, placement):
|
||||||
|
"""Emit a <bpmndi:BPMNDiagram> XML string for the given layout."""
|
||||||
|
if not nodes:
|
||||||
|
return ""
|
||||||
|
max_col = max(c for c, _, _, _ in placement.values())
|
||||||
|
diagram_w = LANE_HEADER_W + LEFT_PAD + (max_col + 1) * COL_W + 60
|
||||||
|
n_lanes = max(1, len(lanes))
|
||||||
|
|
||||||
|
def node_geom(nid):
|
||||||
|
col, lane_idx, sub_idx, sub_n = placement[nid]
|
||||||
|
tag = nodes[nid]
|
||||||
|
w, h = SIZES.get(tag, (100, 80))
|
||||||
|
cx = LANE_HEADER_W + LEFT_PAD + col * COL_W + 50
|
||||||
|
# stagger vertically within the lane if multiple nodes share the bucket
|
||||||
|
lane_cy = TOP_PAD + lane_idx * LANE_H + LANE_H // 2
|
||||||
|
if sub_n > 1:
|
||||||
|
spacing = min(70, (LANE_H - 20) // sub_n)
|
||||||
|
offset = (sub_idx - (sub_n - 1) / 2) * spacing
|
||||||
|
cy = int(lane_cy + offset)
|
||||||
|
else:
|
||||||
|
cy = lane_cy
|
||||||
|
return cx - w // 2, cy - h // 2, w, h
|
||||||
|
|
||||||
|
def node_center(nid):
|
||||||
|
x, y, w, h = node_geom(nid)
|
||||||
|
return x + w // 2, y + h // 2
|
||||||
|
|
||||||
|
def edge_anchor(nid, going_right):
|
||||||
|
x, y, w, h = node_geom(nid)
|
||||||
|
cx, cy = x + w // 2, y + h // 2
|
||||||
|
return ((x + w if going_right else x), cy)
|
||||||
|
|
||||||
|
L = []
|
||||||
|
L.append(' <bpmndi:BPMNDiagram '
|
||||||
|
'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" '
|
||||||
|
'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" '
|
||||||
|
'xmlns:di="http://www.omg.org/spec/DD/20100524/DI" '
|
||||||
|
'id="BPMNDiagram_1">')
|
||||||
|
L.append(' <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="%s">' % plane_id)
|
||||||
|
|
||||||
|
# Lanes (shapes are full-width strips).
|
||||||
|
if lanes:
|
||||||
|
lane_outer_x = LANE_HEADER_W
|
||||||
|
lane_outer_w = diagram_w - LANE_HEADER_W - 20
|
||||||
|
for li, (lid, _, _) in enumerate(lanes):
|
||||||
|
ly = TOP_PAD + li * LANE_H
|
||||||
|
L.append(' <bpmndi:BPMNShape id="Shape_%s" bpmnElement="%s" isHorizontal="true">'
|
||||||
|
% (lid, lid))
|
||||||
|
L.append(' <dc:Bounds x="%d" y="%d" width="%d" height="%d"/>'
|
||||||
|
% (lane_outer_x, ly, lane_outer_w, LANE_H))
|
||||||
|
L.append(' </bpmndi:BPMNShape>')
|
||||||
|
|
||||||
|
# Node shapes.
|
||||||
|
for nid, tag in nodes.items():
|
||||||
|
x, y, w, h = node_geom(nid)
|
||||||
|
L.append(' <bpmndi:BPMNShape id="Shape_%s" bpmnElement="%s">' % (nid, nid))
|
||||||
|
L.append(' <dc:Bounds x="%d" y="%d" width="%d" height="%d"/>' % (x, y, w, h))
|
||||||
|
L.append(' </bpmndi:BPMNShape>')
|
||||||
|
|
||||||
|
# Edges — orthogonal dogleg between source-right and target-left.
|
||||||
|
for fid, s, t in flows:
|
||||||
|
if s not in nodes or t not in nodes:
|
||||||
|
continue
|
||||||
|
sx, sy = edge_anchor(s, going_right=True)
|
||||||
|
tx, ty = edge_anchor(t, going_right=False)
|
||||||
|
if abs(sy - ty) < 4:
|
||||||
|
wps = [(sx, sy), (tx, ty)]
|
||||||
|
elif tx <= sx:
|
||||||
|
# back-edge (cycle) — route via above the source
|
||||||
|
mid_y = min(sy, ty) - 60
|
||||||
|
wps = [(sx, sy), (sx + 20, sy), (sx + 20, mid_y),
|
||||||
|
(tx - 20, mid_y), (tx - 20, ty), (tx, ty)]
|
||||||
|
else:
|
||||||
|
mid_x = (sx + tx) // 2
|
||||||
|
wps = [(sx, sy), (mid_x, sy), (mid_x, ty), (tx, ty)]
|
||||||
|
L.append(' <bpmndi:BPMNEdge id="Edge_%s" bpmnElement="%s">' % (fid, fid))
|
||||||
|
for x, y in wps:
|
||||||
|
L.append(' <di:waypoint x="%d" y="%d"/>' % (x, y))
|
||||||
|
L.append(' </bpmndi:BPMNEdge>')
|
||||||
|
|
||||||
|
L.append(' </bpmndi:BPMNPlane>')
|
||||||
|
L.append(' </bpmndi:BPMNDiagram>')
|
||||||
|
return "\n".join(L) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def annotate_text(text):
|
||||||
|
"""Take BPMN XML text and return XML text with a fresh DI section."""
|
||||||
|
root = ET.fromstring(text)
|
||||||
|
proc = root.find(f"{{{BPMN}}}process")
|
||||||
|
if proc is None:
|
||||||
|
raise ValueError("no <bpmn:process> element")
|
||||||
|
nodes, flows, lanes = collect_model(proc)
|
||||||
|
if not nodes:
|
||||||
|
raise ValueError("no nodes in process")
|
||||||
|
placement = compute_layout(nodes, flows, lanes)
|
||||||
|
di = render_di(proc.get("id"), nodes, flows, lanes, placement)
|
||||||
|
|
||||||
|
text = re.sub(
|
||||||
|
r"\n?\s*<bpmndi:BPMNDiagram[\s\S]*?</bpmndi:BPMNDiagram>\s*\n?",
|
||||||
|
"\n", text, flags=re.MULTILINE)
|
||||||
|
return text.replace("</bpmn:definitions>", di + "</bpmn:definitions>"), \
|
||||||
|
(len(nodes), len(flows), len(lanes))
|
||||||
|
|
||||||
|
|
||||||
|
def annotate_bpmn(path):
|
||||||
|
text = open(path, encoding="utf-8").read()
|
||||||
|
new_text, stats = annotate_text(text)
|
||||||
|
with open(path, "w", encoding="utf-8") as fh:
|
||||||
|
fh.write(new_text)
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
if len(argv) < 2:
|
||||||
|
sys.exit(__doc__.strip())
|
||||||
|
for p in argv[1:]:
|
||||||
|
n, f, l = annotate_bpmn(p)
|
||||||
|
print(f" {p}: {n} nodes / {f} flows / {l} lanes — DI written")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
||||||
@@ -52,4 +52,53 @@ Sistēma: RVS Horizon | Izpildes termiņš: *3 dd laikā no avansa norēķina
|
|||||||
<bpmn:sequenceFlow id="Flow_3" sourceRef="Task_3_5_2_3" targetRef="Task_3_5_2_2"/>
|
<bpmn:sequenceFlow id="Flow_3" sourceRef="Task_3_5_2_3" targetRef="Task_3_5_2_2"/>
|
||||||
<bpmn:sequenceFlow id="Flow_4" sourceRef="Task_3_5_2_1" targetRef="End_1"/>
|
<bpmn:sequenceFlow id="Flow_4" sourceRef="Task_3_5_2_1" targetRef="End_1"/>
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_3_5_2">
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Nodarbinatais" bpmnElement="Lane_Nodarbinatais" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="40" width="780" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_VPC" bpmnElement="Lane_VPC" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="220" width="780" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_1" bpmnElement="Start_1">
|
||||||
|
<dc:Bounds x="122" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_1" bpmnElement="End_1">
|
||||||
|
<dc:Bounds x="462" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_2_1" bpmnElement="Task_3_5_2_1">
|
||||||
|
<dc:Bounds x="260" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_2_2" bpmnElement="Task_3_5_2_2">
|
||||||
|
<dc:Bounds x="600" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_2_3" bpmnElement="Task_3_5_2_3">
|
||||||
|
<dc:Bounds x="600" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_1" bpmnElement="Flow_1">
|
||||||
|
<di:waypoint x="158" y="130"/>
|
||||||
|
<di:waypoint x="260" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_2" bpmnElement="Flow_2">
|
||||||
|
<di:waypoint x="700" y="130"/>
|
||||||
|
<di:waypoint x="720" y="130"/>
|
||||||
|
<di:waypoint x="720" y="70"/>
|
||||||
|
<di:waypoint x="580" y="70"/>
|
||||||
|
<di:waypoint x="580" y="310"/>
|
||||||
|
<di:waypoint x="600" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_3" bpmnElement="Flow_3">
|
||||||
|
<di:waypoint x="700" y="310"/>
|
||||||
|
<di:waypoint x="720" y="310"/>
|
||||||
|
<di:waypoint x="720" y="70"/>
|
||||||
|
<di:waypoint x="580" y="70"/>
|
||||||
|
<di:waypoint x="580" y="130"/>
|
||||||
|
<di:waypoint x="600" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_4" bpmnElement="Flow_4">
|
||||||
|
<di:waypoint x="360" y="130"/>
|
||||||
|
<di:waypoint x="462" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn:definitions>
|
</bpmn:definitions>
|
||||||
|
|||||||
@@ -73,4 +73,68 @@ Sistēma: RVS Horizon | Izpildes termiņš: *3 dd laikā no atskaites apstipri
|
|||||||
<bpmn:sequenceFlow id="Flow_5" sourceRef="Task_3_5_3_1" targetRef="End_1"/>
|
<bpmn:sequenceFlow id="Flow_5" sourceRef="Task_3_5_3_1" targetRef="End_1"/>
|
||||||
<bpmn:sequenceFlow id="Flow_6" sourceRef="Task_3_5_3_2" targetRef="End_2"/>
|
<bpmn:sequenceFlow id="Flow_6" sourceRef="Task_3_5_3_2" targetRef="End_2"/>
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_3_5_3">
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_VPC" bpmnElement="Lane_VPC" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="40" width="950" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Lane_Nodarbinatais" bpmnElement="Lane_Nodarbinatais" isHorizontal="true">
|
||||||
|
<dc:Bounds x="30" y="220" width="950" height="180"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_1" bpmnElement="Start_1">
|
||||||
|
<dc:Bounds x="122" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Start_2" bpmnElement="Start_2">
|
||||||
|
<dc:Bounds x="122" y="292" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_1" bpmnElement="End_1">
|
||||||
|
<dc:Bounds x="802" y="112" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_End_2" bpmnElement="End_2">
|
||||||
|
<dc:Bounds x="462" y="77" width="36" height="36"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_3_1" bpmnElement="Task_3_5_3_1">
|
||||||
|
<dc:Bounds x="600" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_3_2" bpmnElement="Task_3_5_3_2">
|
||||||
|
<dc:Bounds x="260" y="90" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_3_3" bpmnElement="Task_3_5_3_3">
|
||||||
|
<dc:Bounds x="260" y="270" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Shape_Task_3_5_3_4" bpmnElement="Task_3_5_3_4">
|
||||||
|
<dc:Bounds x="430" y="125" width="100" height="80"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_1" bpmnElement="Flow_1">
|
||||||
|
<di:waypoint x="158" y="130"/>
|
||||||
|
<di:waypoint x="260" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_2" bpmnElement="Flow_2">
|
||||||
|
<di:waypoint x="158" y="310"/>
|
||||||
|
<di:waypoint x="260" y="310"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_3" bpmnElement="Flow_3">
|
||||||
|
<di:waypoint x="360" y="310"/>
|
||||||
|
<di:waypoint x="395" y="310"/>
|
||||||
|
<di:waypoint x="395" y="165"/>
|
||||||
|
<di:waypoint x="430" y="165"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_4" bpmnElement="Flow_4">
|
||||||
|
<di:waypoint x="530" y="165"/>
|
||||||
|
<di:waypoint x="565" y="165"/>
|
||||||
|
<di:waypoint x="565" y="130"/>
|
||||||
|
<di:waypoint x="600" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_5" bpmnElement="Flow_5">
|
||||||
|
<di:waypoint x="700" y="130"/>
|
||||||
|
<di:waypoint x="802" y="130"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Edge_Flow_6" bpmnElement="Flow_6">
|
||||||
|
<di:waypoint x="360" y="130"/>
|
||||||
|
<di:waypoint x="411" y="130"/>
|
||||||
|
<di:waypoint x="411" y="95"/>
|
||||||
|
<di:waypoint x="462" y="95"/>
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
</bpmn:definitions>
|
</bpmn:definitions>
|
||||||
|
|||||||
@@ -25,14 +25,19 @@ Examples:
|
|||||||
Dependencies: openpyxl.
|
Dependencies: openpyxl.
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from xml.sax.saxutils import escape
|
from xml.sax.saxutils import escape
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import openpyxl
|
import openpyxl
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit("error: openpyxl is required (pip install openpyxl)")
|
sys.exit("error: openpyxl is required (pip install openpyxl)")
|
||||||
|
|
||||||
|
import bpmn_di
|
||||||
|
|
||||||
BPMN_NS = "http://www.omg.org/spec/BPMN/20100524/MODEL"
|
BPMN_NS = "http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
|
||||||
# RACI actor columns, in register column order, mapped to BPMN lane ids/names.
|
# RACI actor columns, in register column order, mapped to BPMN lane ids/names.
|
||||||
@@ -363,6 +368,7 @@ def cmd_list(path):
|
|||||||
def cmd_emit(path, sub, out):
|
def cmd_emit(path, sub, out):
|
||||||
steps, subs = parse_register(path)
|
steps, subs = parse_register(path)
|
||||||
xml = emit_bpmn(steps, subs, sub)
|
xml = emit_bpmn(steps, subs, sub)
|
||||||
|
xml, _ = bpmn_di.annotate_text(xml)
|
||||||
if out:
|
if out:
|
||||||
with open(out, "w", encoding="utf-8") as fh:
|
with open(out, "w", encoding="utf-8") as fh:
|
||||||
fh.write(xml)
|
fh.write(xml)
|
||||||
|
|||||||
Reference in New Issue
Block a user