Added: soneta-business-xml, soneta-programming-basics
This commit is contained in:
@@ -0,0 +1,305 @@
|
|||||||
|
---
|
||||||
|
name: soneta-business-xml
|
||||||
|
description: >
|
||||||
|
Generator plików business.xml dla platform Soneta (enova365, Soneta Enterprise).
|
||||||
|
Tworzy definicje obiektów biznesowych (tabel, kolumn, relacji, indeksów) zgodne
|
||||||
|
ze schematem XSD. Używaj gdy użytkownik prosi o stworzenie nowego modułu biznesowego,
|
||||||
|
zdefiniowanie obiektów lub encji do przechowywania w bazie danych, utworzenie relacji
|
||||||
|
między obiektami, lub generowanie plików business.xml dla enova365/Soneta Enterprise.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Soneta Business XML Generator
|
||||||
|
|
||||||
|
Skill do generowania plików `business.xml` dla platform firmy Soneta:
|
||||||
|
- **enova365** - system ERP dla firm
|
||||||
|
- **Soneta Enterprise** - platforma enterprise
|
||||||
|
|
||||||
|
Pliki te definiują obiekty biznesowe (encje ORM), które platforma automatycznie mapuje na tabele w bazie danych i generuje klasy C#.
|
||||||
|
|
||||||
|
## Struktura pliku business.xml
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<module xmlns="http://www.enova.pl/schema/business_struct.xsd"
|
||||||
|
name="NazwaModulu"
|
||||||
|
namespace="Soneta.NazwaModulu"
|
||||||
|
versionName="soneta">
|
||||||
|
|
||||||
|
<import>../..</import>
|
||||||
|
<using>Soneta.Core</using>
|
||||||
|
|
||||||
|
<!-- Definicje enum, subrow, interface, table -->
|
||||||
|
</module>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Atrybuty modułu
|
||||||
|
|
||||||
|
| Atrybut | Wymagany | Opis |
|
||||||
|
|---------|----------|------|
|
||||||
|
| `name` | ✓ | Nazwa modułu (np. "Handel", "Kadry") |
|
||||||
|
| `namespace` | ✓ | Namespace C# (np. "Soneta.Handel") |
|
||||||
|
| `versionName` | ✓ | Zazwyczaj "soneta" |
|
||||||
|
| `versionNumber` | | Numer wersji (int) |
|
||||||
|
| `internal` | | true dla modułów wewnętrznych |
|
||||||
|
|
||||||
|
## Atrybuty table
|
||||||
|
|
||||||
|
| Atrybut | Wymagany | Opis |
|
||||||
|
|---------|----------|------|
|
||||||
|
| `name` | ✓ | Nazwa klasy C# (PascalCase, l.poj.) |
|
||||||
|
| `tablename` | ✓ | Nazwa tabeli w bazie danych (PascalCase, l.mn.) |
|
||||||
|
| `guided` | | `Root` = główna tabela programu (dokument, kartoteka) |
|
||||||
|
| `config` | | `true` = tabela konfiguracyjna (tworzona podczas wdrożenia) |
|
||||||
|
| `caption` | | Etykieta pojedynczego rekordu |
|
||||||
|
| `tablecaption` | | Etykieta listy rekordów |
|
||||||
|
|
||||||
|
### Rodzaje tabel
|
||||||
|
|
||||||
|
**Tabele główne (`guided="Root"`):**
|
||||||
|
- Główne obiekty biznesowe: dokumenty, kartoteki (towar, pracownik, kontrahent)
|
||||||
|
- Dostępne z menu głównego programu
|
||||||
|
- Stanowią bazę definicji obiektów biznesowych
|
||||||
|
|
||||||
|
**Tabele eksportowalne (`guided="Exported"`):**
|
||||||
|
- Jak `Root`, ale dodatkowo mogą być eksportowane do innych systemów
|
||||||
|
- Najważniejsze tabele transakcyjne: DokumentHandlowy, Platnosc, DokEwidencja
|
||||||
|
- Używaj dla dokumentów wymagających integracji z systemami zewnętrznymi
|
||||||
|
|
||||||
|
**Tabele szczegółów (bez `guided`):**
|
||||||
|
- Opisują szczegóły obiektów głównych: pozycje dokumentu, kody towaru, adresy
|
||||||
|
- Muszą mieć dokładnie jedną relację z `relguided="inner"` wskazującą na obiekt główny
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (`config="true"`):**
|
||||||
|
- Określają sposób działania programu
|
||||||
|
- Konfiguracja algorytmów, formularzy, wydruków, słowników
|
||||||
|
- Dane tworzone podczas wdrożenia systemu
|
||||||
|
- Przykłady: definicje dokumentów, jednostki miary, stawki VAT
|
||||||
|
|
||||||
|
**Tabele operacyjne (bez `config`):**
|
||||||
|
- Dane zbierane podczas codziennej pracy
|
||||||
|
- Dokumenty, kartoteki, transakcje
|
||||||
|
|
||||||
|
## Elementy wewnętrzne
|
||||||
|
|
||||||
|
### 1. Import i using
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<import>../..</import>
|
||||||
|
<using>Soneta.Core</using>
|
||||||
|
<using>Soneta.CRM</using>
|
||||||
|
```
|
||||||
|
|
||||||
|
- **import** - ścieżka do katalogu z innymi plikami business.xml, do których można referować (np. typy z innych modułów)
|
||||||
|
- **using** - namespace C# dla obiektów używanych w tym business.xml (potrzebne gdy referujesz typy z innych modułów)
|
||||||
|
|
||||||
|
### 2. Enum - definicja typu wyliczeniowego
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<enum name="TypTowaru"/>
|
||||||
|
<enum name="StatusDokumentu"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Enum musi być zdefiniowany w osobnym pliku C# - tutaj tylko deklaracja.
|
||||||
|
|
||||||
|
### 3. Interface - relacje polimorficzne
|
||||||
|
|
||||||
|
Interface może być implementowany przez wiele tabel. Deklaracja samego interfejsu (jego metody/właściwości) jest w kodzie C#. W business.xml deklarujemy tylko nazwę interfejsu, aby móc tworzyć **relacje interface'owe**.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<interface name="IKontrahent"/>
|
||||||
|
<interface name="IPodmiotKasowy"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Relacja interface'owa** - kolumna typu interface może wskazywać na obiekt z dowolnej tabeli implementującej ten interface. W bazie danych zapisywana jest para: `(nazwa_tabeli, ID)`.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Relacja interface'owa - może wskazywać na Osobę, Firmę lub inny obiekt implementujący IKontrahent -->
|
||||||
|
<col name="Kontrahent" type="IKontrahent" required="true"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Subrow - typ złożony (value object)
|
||||||
|
|
||||||
|
Subrow to zagnieżdżony obiekt bez własnej tabeli - przechowywany jako kolumny w tabeli rodzica.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<subrow name="Adres">
|
||||||
|
<col name="Ulica" type="string" length="100"/>
|
||||||
|
<col name="Miasto" type="string" length="50"/>
|
||||||
|
<col name="KodPocztowy" type="string" length="10"/>
|
||||||
|
</subrow>
|
||||||
|
|
||||||
|
<subrow name="NumerDokumentu">
|
||||||
|
<key name="WgSymbolu" keyunique="true">
|
||||||
|
<keycol name="Symbol"/>
|
||||||
|
<keycol name="Numer"/>
|
||||||
|
</key>
|
||||||
|
<col name="Symbol" type="string" length="50"/>
|
||||||
|
<col name="Numer" type="int"/>
|
||||||
|
<col name="Pelny" type="string" length="40"/>
|
||||||
|
</subrow>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Table - główna definicja obiektu biznesowego
|
||||||
|
|
||||||
|
Pełna dokumentacja: [references/table-reference.md](references/table-reference.md)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Towar" tablename="Towary" guided="Root" caption="Towar" tablecaption="Towary">
|
||||||
|
<interface>IElementSlownika</interface>
|
||||||
|
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<col name="Kod" type="string" length="100" required="true" important="true"/>
|
||||||
|
<col name="Nazwa" type="string" length="200" required="true"/>
|
||||||
|
<col name="Cena" type="currency"/>
|
||||||
|
<col name="Aktywny" type="boolean"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Typy danych kolumn
|
||||||
|
|
||||||
|
### Typy proste
|
||||||
|
|
||||||
|
| Typ | Opis | Dodatkowe atrybuty |
|
||||||
|
|-----|------|-------------------|
|
||||||
|
| `string` | Tekst (wczytywany z rekordem) | `length` - wymagane, lub `"max"` dla nieograniczonego |
|
||||||
|
| `text` | Długi tekst (wczytywany na żądanie, osobne SQL) | nie może być kluczem |
|
||||||
|
| `binary` | Dane binarne | nie może być kluczem |
|
||||||
|
| `int` | Liczba całkowita | - |
|
||||||
|
| `double` | Liczba zmiennoprzecinkowa | - |
|
||||||
|
| `decimal` | Liczba z dokładnością do 2 miejsc (kwota bez waluty) | - |
|
||||||
|
| `currency` | Kwota z walutą (para: kwota + waluta) | - |
|
||||||
|
| `doublecy` | Liczba z walutą (para: liczba + waluta) | - |
|
||||||
|
| `percent` | Procent | - |
|
||||||
|
| `boolean` | Tak/Nie | - |
|
||||||
|
| `date` | Data | - |
|
||||||
|
| `time` | Czas | - |
|
||||||
|
| `datetime` | Data i czas | - |
|
||||||
|
| `FromTo` | Okres dat (para: from + to) | - |
|
||||||
|
| `guid` | Unikalny identyfikator | - |
|
||||||
|
|
||||||
|
### Typy relacyjne
|
||||||
|
|
||||||
|
| Typ | Opis | Dodatkowe atrybuty |
|
||||||
|
|-----|------|-------------------|
|
||||||
|
| `NazwaTabeli` | Relacja do innej tabeli | `children`, `delete`, `relname`, `relguided` |
|
||||||
|
| `NazwaInterface` | Relacja interface'owa (polimorficzna) | `children`, `delete`, `relname` |
|
||||||
|
| `NazwaEnum` | Typ wyliczeniowy | - |
|
||||||
|
| `NazwaSubrow` | Typ złożony (value object) | - |
|
||||||
|
|
||||||
|
### Uwagi do typów
|
||||||
|
|
||||||
|
- **`string` vs `text`**: Używaj `string` dla krótszych tekstów (wczytywane z rekordem). Używaj `text` dla długich opisów (wczytywane osobnym zapytaniem SQL).
|
||||||
|
- **`string length="max"`**: Tekst bez ograniczenia rozmiaru, ale wczytywany razem z rekordem.
|
||||||
|
- **`text` i `binary`**: Nie mogą być używane jako klucze (`keyprimary`, `keyunique`).
|
||||||
|
|
||||||
|
## Workflow tworzenia business.xml
|
||||||
|
|
||||||
|
1. **Analiza wymagań** - określ jakie obiekty i relacje są potrzebne
|
||||||
|
2. **Zdefiniuj enumy** - typy wyliczeniowe używane w kolumnach
|
||||||
|
3. **Zdefiniuj interfejsy** - dla relacji polimorficznych (gdy kolumna może wskazywać na różne typy obiektów)
|
||||||
|
4. **Zdefiniuj subrow** - typy złożone (adresy, numery dokumentów)
|
||||||
|
5. **Zdefiniuj tabele** - główne obiekty biznesowe
|
||||||
|
6. **Dodaj relacje** - powiązania między tabelami (zwykłe i interface'owe)
|
||||||
|
7. **Dodaj indeksy** - klucze dla wyszukiwania
|
||||||
|
8. **Waliduj** - sprawdź zgodność ze schematem XSD
|
||||||
|
|
||||||
|
## Szczegółowa dokumentacja
|
||||||
|
|
||||||
|
- **[references/modules-catalog.md](references/modules-catalog.md)** - katalog 34 modułów Soneta, tabele i interfejsy do relacji
|
||||||
|
- **[references/table-reference.md](references/table-reference.md)** - kompletna dokumentacja atrybutów table i col
|
||||||
|
- **[references/relations-guide.md](references/relations-guide.md)** - tworzenie relacji między obiektami
|
||||||
|
- **[references/examples.md](references/examples.md)** - przykłady z rzeczywistych modułów Soneta
|
||||||
|
|
||||||
|
## Konwencje nazewnicze Soneta
|
||||||
|
|
||||||
|
- **Nazwa tabeli (name)**: PascalCase, liczba pojedyncza (np. `Towar`, `DokumentHandlowy`)
|
||||||
|
- **Nazwa w bazie (tablename)**: PascalCase, liczba mnoga (np. `Towary`, `DokHandlowe`)
|
||||||
|
- **Nazwa kolumny**: PascalCase (np. `KodPocztowy`, `DataWystawienia`)
|
||||||
|
- **Klucz**: `Wg` + nazwa kolumny (np. `WgKodu`, `WgNazwy`)
|
||||||
|
- **Namespace**: `Soneta.NazwaModulu`
|
||||||
|
|
||||||
|
### Język nazewnictwa
|
||||||
|
|
||||||
|
- **Obiekty biznesowe** (domenowe) - język **polski**: `Towar`, `Faktura`, `Kontrahent`, `Pracownik`
|
||||||
|
- **Obiekty systemowe** (techniczne) - język **angielski**: `Session`, `Config`, `Cache`, `Runtime`
|
||||||
|
|
||||||
|
## Typowe wzorce
|
||||||
|
|
||||||
|
### Słownik (tabela konfiguracyjna)
|
||||||
|
|
||||||
|
Tabele `config="true"` zawierają dane konfiguracyjne tworzone podczas wdrożenia.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Jednostka" tablename="Jednostki" guided="Root" config="true"
|
||||||
|
caption="Jednostka" tablecaption="Jednostki">
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
<col name="Kod" type="string" length="10" required="true"
|
||||||
|
description="Symbol jednostki używany przy wprowadzaniu ilości."/>
|
||||||
|
<col name="Nazwa" type="string" length="80"
|
||||||
|
description="Pełna nazwa jednostki miary."/>
|
||||||
|
<col name="Blokada" type="boolean"
|
||||||
|
description="Jednostka nie będzie wyświetlana na listach wyboru."/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dokument z pozycjami (master-detail)
|
||||||
|
|
||||||
|
Tabela szczegółów (bez `guided`) musi mieć dokładnie jedną relację `relguided="inner"`.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- TABELA GŁÓWNA (guided="Root") -->
|
||||||
|
<table name="Dokument" tablename="Dokumenty" guided="Root"
|
||||||
|
caption="Dokument" tablecaption="Dokumenty">
|
||||||
|
<key name="WgNumeru" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Numer"/>
|
||||||
|
</key>
|
||||||
|
<col name="Numer" type="string" length="30" required="true"
|
||||||
|
description="Numer dokumentu."/>
|
||||||
|
<col name="Data" type="date" required="true"
|
||||||
|
description="Data wystawienia dokumentu."/>
|
||||||
|
<col name="Kontrahent" type="Kontrahent" required="true"
|
||||||
|
description="Kontrahent, dla którego wystawiono dokument."/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- TABELA SZCZEGÓŁÓW (bez guided, jedna relacja relguided="inner") -->
|
||||||
|
<table name="PozycjaDokumentu" tablename="PozycjeDokumentow"
|
||||||
|
caption="Pozycja" tablecaption="Pozycje dokumentu">
|
||||||
|
<col name="Dokument" type="Dokument"
|
||||||
|
required="true" readonly="true" keyprimary="true"
|
||||||
|
children="Pozycje" delete="cascade" relguided="inner"
|
||||||
|
description="Dokument, do którego należy pozycja."/>
|
||||||
|
<col name="Lp" type="int" required="true" batchfield="false"
|
||||||
|
description="Numer kolejny pozycji."/>
|
||||||
|
<col name="Towar" type="Towar" required="true"
|
||||||
|
description="Towar na pozycji."/>
|
||||||
|
<col name="Ilosc" type="double" required="true"
|
||||||
|
description="Ilość towaru."/>
|
||||||
|
<col name="Cena" type="decimal"
|
||||||
|
description="Cena jednostkowa."/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Historia zmian (wersjonowanie)
|
||||||
|
|
||||||
|
Typ `FromTo` przechowuje okres dat (from + to).
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="CenaHistoria" tablename="CenyHistoria"
|
||||||
|
caption="Historia ceny" tablecaption="Historia cen">
|
||||||
|
<col name="Towar" type="Towar"
|
||||||
|
keyprimary="true" keyclass="History" keyclasscol="Okres"
|
||||||
|
children="HistoriaCen" delete="cascade" relguided="inner"
|
||||||
|
description="Towar, którego dotyczy historia cen."/>
|
||||||
|
<col name="Okres" type="FromTo" required="true"
|
||||||
|
description="Okres obowiązywania ceny."/>
|
||||||
|
<col name="CenaNetto" type="decimal"
|
||||||
|
description="Cena netto w okresie."/>
|
||||||
|
<col name="CenaBrutto" type="decimal"
|
||||||
|
description="Cena brutto w okresie."/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns="http://www.enova.pl/schema/business_struct.xsd" targetNamespace="http://www.enova.pl/schema/business_struct.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
|
||||||
|
<xs:simpleType name="RequiredType">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:enumeration value="true"/>
|
||||||
|
<xs:enumeration value="false"/>
|
||||||
|
<xs:enumeration value="noverified"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
<xs:simpleType name="ReadonlyType">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:enumeration value="true"/>
|
||||||
|
<xs:enumeration value="false"/>
|
||||||
|
<xs:enumeration value="set"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
<xs:simpleType name="LocalizationType">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:enumeration value="none"/>
|
||||||
|
<xs:enumeration value="dictionary"/>
|
||||||
|
<xs:enumeration value="db"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
|
||||||
|
<xs:element name="module">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice maxOccurs="unbounded">
|
||||||
|
<xs:element name="import" type="xs:string" />
|
||||||
|
<xs:element name="using" type="xs:string" />
|
||||||
|
<xs:element name="customcode" type="xs:string" />
|
||||||
|
<xs:element name="simpletype">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice maxOccurs="unbounded">
|
||||||
|
<xs:element name="cstype" type="xs:string" />
|
||||||
|
<xs:element name="cscreator" type="xs:string" />
|
||||||
|
<xs:element name="csinitializer" type="xs:string" />
|
||||||
|
<xs:element name="nullcondition" type="xs:string" />
|
||||||
|
<xs:element name="null" type="xs:string" />
|
||||||
|
<xs:element name="attribute" type="xs:string" />
|
||||||
|
<xs:element name="setter" type="xs:string" />
|
||||||
|
<xs:element maxOccurs="unbounded" name="dbfield">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="type" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="postfix" type="xs:string" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element maxOccurs="unbounded" name="subrow">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="key" type="keyType">
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="col" type="colType">
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="enum">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="interface">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="table">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice maxOccurs="unbounded">
|
||||||
|
<xs:element maxOccurs="unbounded" name="interface" type="xs:string" />
|
||||||
|
<xs:element maxOccurs="unbounded" name="key" type="keyType">
|
||||||
|
</xs:element>
|
||||||
|
<xs:element maxOccurs="unbounded" name="col" type="colType"></xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="tablename" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="warnings" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="name8" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="guided" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="config" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="caption" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="tablecaption" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="namespace" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="lock" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="cached" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="timestamp" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="optimisticlocking" type="xs:boolean" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="namespace" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="versionName" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="versionNumber" type="xs:int" default="0" use="optional" />
|
||||||
|
<xs:attribute name="snapshotsDb" type="xs:boolean" default="false" use="optional" />
|
||||||
|
<xs:attribute name="internal" type="xs:boolean" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xs:complexType name="colType">
|
||||||
|
<xs:sequence minOccurs="0">
|
||||||
|
<xs:choice maxOccurs="unbounded">
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="attribute" type="xs:string" />
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="verifier">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="onadded" type="xs:boolean" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="keycol">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="keyinclude">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="type" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="readonly" type="ReadonlyType" use="optional" />
|
||||||
|
<xs:attribute name="required" type="RequiredType" use="optional" />
|
||||||
|
<xs:attribute name="localization" type="LocalizationType" use="optional" />
|
||||||
|
<xs:attribute name="setonlynull" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="reldefault" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="keyunique" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="relname" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="relguided" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="delete" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="length" type="xs:unsignedInt" use="optional" />
|
||||||
|
<xs:attribute name="category" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="modifier" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="selector" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="batchfield" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="children" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="childrenclass" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="name12" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="cstype" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="relright" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="fulltext" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="description" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="caption" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="keyclass" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="keyclasscol" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="keyprimary" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="lock" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="important" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="specialaccess" type="xs:boolean" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
<xs:complexType name="keyType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:choice maxOccurs="unbounded">
|
||||||
|
<xs:element maxOccurs="unbounded" name="keycol">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element minOccurs="0" maxOccurs="unbounded" name="keyinclude">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="keyunique" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="keyprimary" type="xs:boolean" use="optional" />
|
||||||
|
<xs:attribute name="keyclass" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="keyclasscol" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="lock" type="xs:string" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,353 @@
|
|||||||
|
# Przykłady z modułów enova365
|
||||||
|
|
||||||
|
## Spis treści
|
||||||
|
|
||||||
|
1. [Prosty słownik (Jednostka)](#prosty-słownik)
|
||||||
|
2. [Główna encja (Towar)](#główna-encja)
|
||||||
|
3. [Master-Detail (Przecena z pozycjami)](#master-detail)
|
||||||
|
4. [Konfiguracja z historią](#konfiguracja-z-historią)
|
||||||
|
5. [Subrow (typy złożone)](#subrow-typy-złożone)
|
||||||
|
6. [Kompletny moduł](#kompletny-moduł)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prosty słownik
|
||||||
|
|
||||||
|
### Jednostka miary (z Towary)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Jednostka" tablename="Jednostki" guided="Root" config="true"
|
||||||
|
caption="Jednostka" tablecaption="Jednostki">
|
||||||
|
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<col name="Kod" type="string" length="10" localization="dictionary"
|
||||||
|
required="true" important="true"
|
||||||
|
description="Nazwa jednostki wykorzystywana przy wprowadzaniu ilości."/>
|
||||||
|
<col name="Opis" type="string" length="80" localization="dictionary"
|
||||||
|
description="Opis jednostki."/>
|
||||||
|
<col name="Precyzja" type="int"
|
||||||
|
description="Precyzja zaokrąglenia ilości towaru"/>
|
||||||
|
<col name="Typ" type="TypJednostki"
|
||||||
|
description="Typ jednostki: masa, długość, czas, itp."/>
|
||||||
|
<col name="Blokada" type="boolean" important="true"
|
||||||
|
description="Jednostka nie będzie wyświetlana na listach."/>
|
||||||
|
<col name="Uzupelniajaca" type="boolean"
|
||||||
|
description="Jednostka uzupełniająca dla deklaracji UE."/>
|
||||||
|
<col name="JednostkaDlugosci" type="Jednostka"
|
||||||
|
description="Powiązana jednostka długości."/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cechy:**
|
||||||
|
- `config="true"` - tabela konfiguracyjna
|
||||||
|
- `guided="Root"` - dostępna z menu głównego
|
||||||
|
- `localization="dictionary"` - tłumaczenie przez słownik
|
||||||
|
- Relacja zwrotna (`JednostkaDlugosci`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Główna encja
|
||||||
|
|
||||||
|
### Towar (fragment z Towary)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Towar" tablename="Towary" guided="Root" optimisticlocking="true">
|
||||||
|
|
||||||
|
<interface>IElementSlownika</interface>
|
||||||
|
<interface>IKodowany</interface>
|
||||||
|
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
<key name="WgNazwy">
|
||||||
|
<keycol name="Nazwa"/>
|
||||||
|
</key>
|
||||||
|
<key name="WgEAN">
|
||||||
|
<keycol name="EAN"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- OGÓLNE -->
|
||||||
|
<col name="Kod" type="string" length="100" category="Ogólne"
|
||||||
|
required="true" important="true"
|
||||||
|
description="Symbol, skrócona nazwa towaru"/>
|
||||||
|
<col name="Typ" type="TypTowaru" required="true" category="Ogólne"
|
||||||
|
important="true"
|
||||||
|
description="Określa czy towar, usługa, produkt"/>
|
||||||
|
<col name="Nazwa" type="string" length="200" required="true"
|
||||||
|
category="Ogólne" important="true"
|
||||||
|
description="Nazwa towaru na dokumentach.">
|
||||||
|
<verifier name="Towar.NazwaVerifier"/>
|
||||||
|
</col>
|
||||||
|
<col name="EAN" type="string" length="130" category="Ogólne"
|
||||||
|
description="Kod kreskowy do wyszukiwania.">
|
||||||
|
<verifier name="Towar.EANUniqueVerifier"/>
|
||||||
|
</col>
|
||||||
|
|
||||||
|
<!-- RELACJE -->
|
||||||
|
<col name="Jednostka" type="Jednostka" required="true" category="Ogólne"
|
||||||
|
description="Podstawowa jednostka magazynowa."
|
||||||
|
relname="Jednostka towarowa"/>
|
||||||
|
<col name="DefinicjaStawki" type="DefinicjaStawkiVat" required="true"
|
||||||
|
category="Ogólne"
|
||||||
|
description="Stawka VAT dla sprzedaży"
|
||||||
|
relname="Stawka VAT towaru"/>
|
||||||
|
<col name="Dostawca" type="Kontrahent" category="Generowanie zamówień"
|
||||||
|
relname="Dostawca towaru"
|
||||||
|
children="Towary"
|
||||||
|
description="Standardowy dostawca towaru.">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</col>
|
||||||
|
|
||||||
|
<!-- CENY -->
|
||||||
|
<col name="Narzut" type="percent" category="Ceny"
|
||||||
|
description="Narzut do wyliczania ceny hurtowej"/>
|
||||||
|
<col name="Marza" type="percent" caption="Marża" category="Ceny"
|
||||||
|
description="Marża do wyliczania ceny detalicznej"/>
|
||||||
|
<col name="CenaZakupuKartotekowa" type="doublecy" category="Ceny"/>
|
||||||
|
|
||||||
|
<!-- DODATKOWE -->
|
||||||
|
<col name="Blokada" type="boolean" category="Dodatkowe"
|
||||||
|
description="Towar niewidoczny na listach wyboru.">
|
||||||
|
<verifier name="Towar.BlokadaVerifier" onadded="false"/>
|
||||||
|
</col>
|
||||||
|
<col name="Opis" type="text" category="Opis na dokumencie"
|
||||||
|
description="Rozszerzony opis towaru."/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Master-Detail
|
||||||
|
|
||||||
|
### Przecena okresowa z pozycjami (z Towary)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- MASTER: Definicja przeceny -->
|
||||||
|
<table name="PrzecenaOkresowa" tablename="PrzecenyOkres" name8="PrzcOkr"
|
||||||
|
guided="Root">
|
||||||
|
<key keyunique="true" name="WgNazwy" keyprimary="true">
|
||||||
|
<keycol name="Cel"/>
|
||||||
|
<keycol name="Nazwa"/>
|
||||||
|
</key>
|
||||||
|
<key name="Zatwierdzone">
|
||||||
|
<keycol name="Zatwierdzona"/>
|
||||||
|
<keycol name="Cel"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<col name="Cel" type="CelPrzecenyOkresowej" selector="true" readonly="true"/>
|
||||||
|
<col name="Nazwa" type="string" length="32" required="true"
|
||||||
|
description="Nazwa przeceny okresowej (promocji)."/>
|
||||||
|
<col name="Okres" type="FromTo" required="true"
|
||||||
|
description="Okres obowiązywania przeceny okresowej."/>
|
||||||
|
<col name="Zatwierdzona" type="boolean"
|
||||||
|
description="Czy promocja jest zatwierdzona."/>
|
||||||
|
<col name="Typ" type="TypPrzecenyOkresowej"/>
|
||||||
|
<col name="Kontrahent" type="Kontrahent"
|
||||||
|
description="Kontrahent dla promocji indywidualnej."/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- DETAIL: Pozycje przeceny -->
|
||||||
|
<table name="PrzecenaOkresowaTowaru" tablename="PrzecenyOkresTwr"
|
||||||
|
name8="PrzcOkrT">
|
||||||
|
<col name="PrzecenaOkresowa" type="PrzecenaOkresowa"
|
||||||
|
children="PrzecenyTowarow"
|
||||||
|
delete="cascade"
|
||||||
|
keyprimary="true">
|
||||||
|
<attribute>Context</attribute>
|
||||||
|
<keycol name="Towar"/>
|
||||||
|
</col>
|
||||||
|
<col name="Towar" type="Towar" required="true"
|
||||||
|
children="Przeceny"
|
||||||
|
description="Towar, którego dotyczy przecena.">
|
||||||
|
<attribute>Context</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="Netto" type="doublecy" category="Cena"
|
||||||
|
caption="Cena promocyjna netto"/>
|
||||||
|
<col name="Brutto" type="doublecy" category="Cena"
|
||||||
|
caption="Cena promocyjna brutto"/>
|
||||||
|
<col name="Rabat" type="percent" modifier="protected" category="Cena"
|
||||||
|
caption="Rabat promocyjny"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Konfiguracja z historią
|
||||||
|
|
||||||
|
### Procedura SME z historią (z Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- GŁÓWNA TABELA -->
|
||||||
|
<table name="KrajSME" tablename="KrajeSME" caption="Kraj SME"
|
||||||
|
tablecaption="Kraje SME" config="true" guided="Root">
|
||||||
|
<col name="Kraj" type="KrajTbl" caption="Kraj"
|
||||||
|
required="true" keyunique="true" keyprimary="true"/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- HISTORIA -->
|
||||||
|
<table name="ProceduraSME" tablename="ProcedurySME" caption="Procedura SME"
|
||||||
|
tablecaption="Procedury SME" config="true">
|
||||||
|
<col name="Kraj" type="KrajSME"
|
||||||
|
readonly="true" required="true"
|
||||||
|
keyprimary="true"
|
||||||
|
keyclass="History"
|
||||||
|
keyclasscol="Aktualnosc"
|
||||||
|
children="Historia"
|
||||||
|
relname="Dane historyczne procedury SME"
|
||||||
|
relguided="inner"
|
||||||
|
delete="cascade"
|
||||||
|
description="Kraj SME"/>
|
||||||
|
<col name="Aktywna" type="boolean" caption="Aktywna procedura SME"/>
|
||||||
|
<col name="Aktualnosc" type="FromTo" required="true"
|
||||||
|
caption="Okres obowiązywania"/>
|
||||||
|
<col name="ProgObrotu" type="currency" caption="Próg obrotu"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Subrow (typy złożone)
|
||||||
|
|
||||||
|
### DefinicjaCyklu (z Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<subrow name="DefinicjaCyklu">
|
||||||
|
<col name="Krotnosc" type="int" modifier="public virtual"
|
||||||
|
description="Ile razy cykl będzie powtórzony.">
|
||||||
|
<attribute>Browsable(false)</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="Interwal" type="int" modifier="public virtual"/>
|
||||||
|
<col name="Typ" type="DefinicjaCykluTyp" modifier="public virtual"
|
||||||
|
description="Rodzaj cyklu (jednostka interwału)."/>
|
||||||
|
<col name="Czas" type="time"
|
||||||
|
description="Czas wystąpienia cyklu."/>
|
||||||
|
<col name="PozycjaDnia" type="DefinicjaCykluPozycjaDnia"
|
||||||
|
description="Pozycja dnia w okresie."/>
|
||||||
|
<col name="RodzajTerminu" type="DefinicjaCykluRodzajTerminu"
|
||||||
|
modifier="public virtual"/>
|
||||||
|
<col name="SposobNaDniWolne" type="DefinicjaCykluSposobNaDniWolne"
|
||||||
|
specialaccess="true"
|
||||||
|
description="Zachowanie gdy cykl wypada w dzień wolny."/>
|
||||||
|
<col name="Termin" type="int" readonly="set" modifier="protected"
|
||||||
|
description="Termin wystąpienia (wartość wewnętrzna).">
|
||||||
|
<attribute>Browsable(false)</attribute>
|
||||||
|
</col>
|
||||||
|
</subrow>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adres (z Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<subrow name="Adres">
|
||||||
|
<col name="KodPocztowy" type="int" description="Kod pocztowy">
|
||||||
|
<attribute>MaskEdit("00-000", SaveLiteral=false)</attribute>
|
||||||
|
<attribute>SqlResolving(IgnoreDashes=true, NoDashesData=true)</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="ZagranicznyKodPocztowy" type="string" length="11"/>
|
||||||
|
<col name="Poczta" type="string" length="56">
|
||||||
|
<attribute>Dictionary("Miejscowość")</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="Miejscowosc" type="string" length="56">
|
||||||
|
<attribute>Dictionary("Miejscowość")</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="Ulica" type="string" length="80">
|
||||||
|
<attribute>Dictionary("Ulica")</attribute>
|
||||||
|
</col>
|
||||||
|
<col name="NrDomu" type="string" length="10"/>
|
||||||
|
<col name="NrLokalu" type="string" length="10"/>
|
||||||
|
<col name="Wojewodztwo" type="Wojewodztwa"/>
|
||||||
|
</subrow>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kompletny moduł
|
||||||
|
|
||||||
|
### Przykład prostego modułu
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<module xmlns="http://www.enova.pl/schema/business_struct.xsd"
|
||||||
|
name="Projekty"
|
||||||
|
namespace="Soneta.Projekty"
|
||||||
|
versionName="soneta">
|
||||||
|
|
||||||
|
<!-- Ścieżka do katalogu z innymi business.xml (względna od tego pliku) -->
|
||||||
|
<!-- Pozwala referować typy z innych modułów np. Kontrahent, Pracownik -->
|
||||||
|
<import>../..</import>
|
||||||
|
|
||||||
|
<!-- Namespaces C# potrzebne do użycia typów z innych modułów -->
|
||||||
|
<using>Soneta.Core</using>
|
||||||
|
<using>Soneta.CRM</using> <!-- dla Kontrahent -->
|
||||||
|
<using>Soneta.Kadry</using> <!-- dla Pracownik -->
|
||||||
|
|
||||||
|
<!-- ENUMY -->
|
||||||
|
<enum name="StatusProjektu"/>
|
||||||
|
<enum name="PriorytetProjektu"/>
|
||||||
|
<enum name="TypZadania"/>
|
||||||
|
|
||||||
|
<!-- INTERFEJSY -->
|
||||||
|
<interface name="IProjektHost"/>
|
||||||
|
|
||||||
|
<!-- SUBROW -->
|
||||||
|
<subrow name="OkresProjektu">
|
||||||
|
<col name="DataRozpoczecia" type="date"/>
|
||||||
|
<col name="DataZakonczenia" type="date"/>
|
||||||
|
<col name="Budzet" type="currency"/>
|
||||||
|
</subrow>
|
||||||
|
|
||||||
|
<!-- TABELE -->
|
||||||
|
<table name="Projekt" tablename="Projekty" guided="Root"
|
||||||
|
caption="Projekt" tablecaption="Projekty">
|
||||||
|
<interface>IRightsSource</interface>
|
||||||
|
<interface>IProjektHost</interface>
|
||||||
|
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
<key name="WgKlienta">
|
||||||
|
<keycol name="Klient"/>
|
||||||
|
<keycol name="Status"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<col name="Kod" type="string" length="20" required="true"
|
||||||
|
important="true" category="Ogólne"/>
|
||||||
|
<col name="Nazwa" type="string" length="200" required="true"
|
||||||
|
category="Ogólne"/>
|
||||||
|
<col name="Klient" type="Kontrahent" required="true"
|
||||||
|
category="Ogólne"
|
||||||
|
relname="Projekty klienta" children="Projekty"/>
|
||||||
|
<col name="Kierownik" type="Pracownik" category="Ogólne"
|
||||||
|
relname="Projekty kierownika"/>
|
||||||
|
<col name="Status" type="StatusProjektu" category="Ogólne"
|
||||||
|
selector="true"/>
|
||||||
|
<col name="Priorytet" type="PriorytetProjektu" category="Ogólne"/>
|
||||||
|
<col name="Okres" type="OkresProjektu" category="Terminy"/>
|
||||||
|
<col name="Opis" type="text" category="Dodatkowe"/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table name="Zadanie" tablename="Zadania"
|
||||||
|
caption="Zadanie" tablecaption="Zadania">
|
||||||
|
<col name="Projekt" type="Projekt"
|
||||||
|
required="true" readonly="true"
|
||||||
|
keyprimary="true"
|
||||||
|
children="Zadania"
|
||||||
|
delete="cascade"
|
||||||
|
relguided="inner"
|
||||||
|
relname="Zadania projektu"/>
|
||||||
|
<col name="Lp" type="int" required="true" batchfield="false"/>
|
||||||
|
<col name="Nazwa" type="string" length="200" required="true"/>
|
||||||
|
<col name="Typ" type="TypZadania"/>
|
||||||
|
<col name="Wykonawca" type="Pracownik"
|
||||||
|
relname="Zadania pracownika" children="Zadania"/>
|
||||||
|
<col name="TerminOd" type="date"/>
|
||||||
|
<col name="TerminDo" type="date"/>
|
||||||
|
<col name="Wykonane" type="boolean"/>
|
||||||
|
<col name="Opis" type="text"/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</module>
|
||||||
|
```
|
||||||
@@ -0,0 +1,525 @@
|
|||||||
|
# Katalog modułów Soneta
|
||||||
|
|
||||||
|
Katalog modułów dla platform Soneta (enova365, Soneta Enterprise).
|
||||||
|
|
||||||
|
## Spis treści
|
||||||
|
|
||||||
|
1. [Architektura: Konfiguracja vs Operacje](#architektura-konfiguracja-vs-operacje)
|
||||||
|
2. [Lista modułów](#lista-modułów)
|
||||||
|
3. [Najważniejsze typy do relacji](#najważniejsze-typy-do-relacji)
|
||||||
|
4. [Popularne Subrow](#popularne-subrow)
|
||||||
|
5. [Interfejsy](#interfejsy)
|
||||||
|
6. [Moduły szczegółowo](#moduły-szczegółowo)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architektura: Konfiguracja vs Operacje
|
||||||
|
|
||||||
|
enova365 stosuje wzorzec **Definicja → Operacja**, gdzie:
|
||||||
|
|
||||||
|
- **Tabele konfiguracyjne (`config="true"`)** - definiują zachowanie systemu
|
||||||
|
- Tworzone podczas wdrożenia
|
||||||
|
- Określają algorytmy, nazwy, numerację, sposób przetwarzania
|
||||||
|
- Często mają prefiks/sufiks: `Definicja`, `Def`, `Config`
|
||||||
|
|
||||||
|
- **Tabele operacyjne** - przechowują dane transakcyjne
|
||||||
|
- Tworzone podczas codziennej pracy
|
||||||
|
- Ich zachowanie określa powiązana definicja
|
||||||
|
|
||||||
|
### Przykłady par Definicja → Operacja
|
||||||
|
|
||||||
|
| Definicja (config) | Operacja | Opis |
|
||||||
|
|-------------------|----------|------|
|
||||||
|
| `DefinicjaDokumentu` | `DokEwidencja` | Definiuje typ dokumentu, numerację, zachowanie |
|
||||||
|
| `DefDokHandlowego` | `DokumentHandlowy` | Definiuje typ dokumentu handlowego |
|
||||||
|
| `DefinicjaElementu` | `WypElement` | Definiuje element wypłaty, algorytm naliczania |
|
||||||
|
| `DefinicjaListyPlac` | `ListaPlac` | Definiuje typ listy płac |
|
||||||
|
| `DefinicjaNieobecnosci` | nieobecności w kalendarzu | Definiuje typ nieobecności |
|
||||||
|
| `DefinicjaSzkolenia` | `RealizacjaSzkolenia` | Definiuje typ szkolenia |
|
||||||
|
| `DefDokHandlowego` | `DokumentHandlowy` | Definiuje fakturę, WZ, PZ, itd. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Lista modułów
|
||||||
|
|
||||||
|
| Moduł | Namespace | Opis |
|
||||||
|
|-------|-----------|------|
|
||||||
|
| Business | Soneta.Business.Db | Definicje systemowe, operatorzy, uprawnienia |
|
||||||
|
| Core | Soneta.Core | Definicje dokumentów, stawki VAT, oddziały, adresy |
|
||||||
|
| CRM | Soneta.CRM | Kontrahenci, banki, urzędy, kontakty |
|
||||||
|
| Kadry | Soneta.Kadry | Pracownicy, umowy, wydziały |
|
||||||
|
| Kalend | Soneta.Kalend | Kalendarze, grafiki pracy, RCP, nieobecności |
|
||||||
|
| Place | Soneta.Place | Listy płac, wypłaty, elementy wynagrodzenia |
|
||||||
|
| Handel | Soneta.Handel | Dokumenty handlowe, definicje dokumentów |
|
||||||
|
| Towary | Soneta.Towary | Towary, jednostki, ceny, kody CN |
|
||||||
|
| Magazyny | Soneta.Magazyny | Magazyny, okresy magazynowe |
|
||||||
|
| Kasa | Soneta.Kasa | Płatności, rachunki bankowe, formy płatności |
|
||||||
|
| Ksiega | Soneta.Ksiega | Konta, dekrety, schematy księgowe |
|
||||||
|
| SrodkiTrwale | Soneta.SrodkiTrwale | Środki trwałe, amortyzacja |
|
||||||
|
| Waluty | Soneta.Waluty | Waluty, tabele kursowe |
|
||||||
|
| Deklaracje | Soneta.Deklaracje | Deklaracje podatkowe |
|
||||||
|
| EwidencjaVat | Soneta.EwidencjaVat | Ewidencja VAT |
|
||||||
|
| Delegacje | Soneta.Delegacje | Delegacje krajowe i zagraniczne |
|
||||||
|
| HR | Soneta.HR | Oceny, rekrutacja, szkolenia, uprawnienia |
|
||||||
|
| HR2 | Soneta.HR2 | Opisy stanowisk, kompetencje, cele |
|
||||||
|
| Oceny | Soneta.Oceny | System ocen pracowniczych |
|
||||||
|
| Produkcja | Soneta.Produkcja | Technologie, operacje produkcyjne |
|
||||||
|
| ProdukcjaPro | Soneta.ProdukcjaPro | Zaawansowana produkcja, zlecenia |
|
||||||
|
| Zadania | Soneta.Zadania | Projekty, zadania, kampanie, budżety |
|
||||||
|
| Windykacja | Soneta.Windykacja | Sprawy windykacyjne |
|
||||||
|
| Support | Soneta.Support | Zgłoszenia serwisowe (tickety) |
|
||||||
|
| Samochodowka | Soneta.Samochodowka | Ewidencja przejazdów, pojazdy |
|
||||||
|
| Vehicles | Soneta.Vehicles | Flota pojazdów, rezerwacje |
|
||||||
|
| RealEstate | Soneta.RealEstate | Nieruchomości, stanowiska pracy |
|
||||||
|
| RMK | Soneta.RMK | Rozliczenia międzyokresowe kosztów |
|
||||||
|
| BI | Soneta.BI | Business Intelligence, dashboardy |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Najważniejsze typy do relacji
|
||||||
|
|
||||||
|
### Podmioty i kontrahenci (CRM)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.CRM</using>
|
||||||
|
|
||||||
|
<col name="Kontrahent" type="Kontrahent" relname="..."/>
|
||||||
|
<col name="Bank" type="Bank" relname="..."/>
|
||||||
|
<col name="UrzadSkarbowy" type="UrzadSkarbowy" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pracownicy i kadry (Kadry)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Kadry</using>
|
||||||
|
|
||||||
|
<col name="Pracownik" type="Pracownik" relname="..."/>
|
||||||
|
<col name="Wydzial" type="Wydzial" relname="..."/>
|
||||||
|
<col name="Umowa" type="Umowa" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Towary i magazyny (Towary, Magazyny)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Towary</using>
|
||||||
|
<using>Soneta.Magazyny</using>
|
||||||
|
|
||||||
|
<col name="Towar" type="Towar" relname="..."/>
|
||||||
|
<col name="Jednostka" type="Jednostka" relname="..."/>
|
||||||
|
<col name="Magazyn" type="Magazyn" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dokumenty handlowe (Handel)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Handel</using>
|
||||||
|
|
||||||
|
<col name="DokumentHandlowy" type="DokumentHandlowy" relname="..."/>
|
||||||
|
<col name="Definicja" type="DefDokHandlowego" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Finanse i płatności (Kasa, Waluty)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Kasa</using>
|
||||||
|
<using>Soneta.Waluty</using>
|
||||||
|
|
||||||
|
<col name="Waluta" type="Waluta" relname="..."/>
|
||||||
|
<col name="FormaPlatnosci" type="FormaPlatnosci" relname="..."/>
|
||||||
|
<col name="Platnosc" type="Platnosc" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Definicje i konfiguracja (Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Core</using>
|
||||||
|
|
||||||
|
<col name="Definicja" type="DefinicjaDokumentu" relname="..."/>
|
||||||
|
<col name="StawkaVat" type="DefinicjaStawkiVat" relname="..."/>
|
||||||
|
<col name="Oddzial" type="OddzialFirmy" relname="..."/>
|
||||||
|
<col name="Kraj" type="KrajTbl" relname="..."/>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Popularne Subrow
|
||||||
|
|
||||||
|
### Adres (Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Core</using>
|
||||||
|
<col name="Adres" type="Adres"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Zawiera: KodPocztowy, Miejscowosc, Ulica, NrDomu, NrLokalu, Poczta, Wojewodztwo
|
||||||
|
|
||||||
|
### Osoba (Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="OsobaKontaktowa" type="Osoba"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Zawiera: Imie, Nazwisko, DrugieImie, PESEL, DataUrodzenia
|
||||||
|
|
||||||
|
### Kontakt (Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="DaneKontaktowe" type="Kontakt"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Zawiera: Telefon, Fax, Email, WWW
|
||||||
|
|
||||||
|
### NumerDokumentu (Core)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Numer" type="NumerDokumentu"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Zawiera: Symbol, Numer, Pelny
|
||||||
|
|
||||||
|
### FromTo (wbudowany)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Okres" type="FromTo"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Zawiera: From (data od), To (data do)
|
||||||
|
|
||||||
|
### BruttoNetto, BruttoNettoCy (Handel)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<using>Soneta.Handel</using>
|
||||||
|
<col name="Wartosc" type="BruttoNetto"/>
|
||||||
|
<col name="WartoscWalutowa" type="BruttoNettoCy"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interfejsy
|
||||||
|
|
||||||
|
| Interface | Moduł | Opis |
|
||||||
|
|-----------|-------|------|
|
||||||
|
| `IKontrahent` | Core | Kontrahent (relacja polimorficzna) |
|
||||||
|
| `IPodmiotKasowy` | Kasa | Podmiot kasowy |
|
||||||
|
| `IRightsSource` | Business | Źródło uprawnień |
|
||||||
|
| `IGuidedRow` | Business | Wiersz z nawigacją |
|
||||||
|
| `IDokument` | Core | Dokument |
|
||||||
|
| `IDokumentKasowy` | Core | Dokument kasowy |
|
||||||
|
| `IDokumentPlatny` | Core | Dokument płatny |
|
||||||
|
| `IDokumentKsiegowalny` | Core | Dokument księgowalny |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Moduły szczegółowo
|
||||||
|
|
||||||
|
### Core (Soneta.Core)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefinicjaDokumentu, DefinicjaDokumentuOA, CentrumKosztow, ZrodloFinansowania, RodzajZrodla, DefinicjaPodzielnikaKosztow, DefinicjaStawkiVat, DefinicjaStawkiAkcyzy, OddzialFirmy, KrajTbl, IsoProcedura, StrukturaOrganizacyjna, DefinicjaElementuStrukturyOrganizacyjnej, DefTeczki, RodzajKontaktu, DomyslnyCel, Slownik, SlownikZewn, SystemZewn, ScheduleDefs, ProceduryVAT, WarningDefs, KrajSME
|
||||||
|
|
||||||
|
**Tabele eksportowalne (guided=Exported):**
|
||||||
|
DokEwidencja
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
HistoriaDanychOddziału, HistoriaDanychFirmyBase, ElementStrukturyOrganizacyjnej, Teczka, Discussion, Konwersacja, Aktualnosci
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
DefinicjaCyklu, DefinicjaNumeracji, NumerDokumentu, Adres, AdresRozszerzony, Kontakt, Osoba, StawkaVat
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CRM (Soneta.CRM)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefKategKth, FormaPrawna, RoleOpiekun, AuthProvider, AuthAzureConfig, SzablonSms, ZrodloKontaktu, Branza, DefTransakcji, StanyTransakcji, DefLeadow, StanyLeada, PriorytetyLeadow, PriorytetyTran
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Kontrahent, Bank, UrzadSkarbowy, UrzadCelny, OddziałZUS, InstytucjaFinansowaPPK, Lokalizacja, OsobaKontrahent, WizytowkaFirmy, KontoPocztowe, WiadomoscEmail, SzablonEmail, Transakcja, Lead, Opiekun
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
PowiazaniePodmiotu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Kadry (Soneta.Kadry)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefPodstawyStazu, DefinicjaWydziału, Wydzial, GrupaZaszeregowania, TytulUbezpieczenia4, KodPracyWSzególnychWarunkachCharakterze, ZestawDodatków, DefinicjaAkordu, DefinicjaOświadczenia, DefinicjaBadaniaLekarskiego, DefSzkolenBHP, DefJezykowObcych, DefFundPozycz, KatCzynnSzkod, DefCzynnSzkod, KatZglSygnal
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Pracownik, Umowa, Dodatek, CzlonekRodziny, Akord, WniosekUrlopowy, OświadczeniePracownika, NagrodaKara, Pozyczka, ZgodaNaEdycję, KorektaZajęciaKomorniczego, UmowyZewnetrzne, CzynnSzkodPrac
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Zaszeregowanie, Etat, StazPracyPracownika, Urodzony, DokumentOsoby, Obywatelstwo, StopienNiepelnosp, DaneZUS, DanePFRON, Ubezpieczenia, UmowaOPrace, ZawarcieUmowy, RozwiazanieUmowy, StatystykaGUS, PodatkiInfo, StanRodzinny
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Kalend (Soneta.Kalend)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
CzytnikRCP, DefinicjaLimitu, DefinicjaStrefy, DefinicjaDnia, DefinicjaNieobecnosci, DefinicjaGrafikaPracy, DefinicjaZestawieniaCzasu, DefAlgorytmRCP, DefinicjaRozliczeniaCzasuPracy, DefinicjaRodzajuPracyZdalnej, DefinicjaZdarzeniaRCP, DefinicjaAktualizacjiKalendarza, DefWeryfKalend
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
KalendarzBase, GrafikPracy, RozliczenieCzasuPracy, ElementRozliczeniaCzasuPracy, WniosekPracyZdalnej, DokumentAktualizacjiKalendarza, ObiektDoPlanowania
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
CzasPracy, Nadgodziny, Nocne, ZwolnienieZUS, UrlopMacierzyński, UrlopWychowawczy, UrlopWypoczynkowy, ZLA
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Place (Soneta.Place)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefinicjaListyPlac, DefinicjaElementu, PozycjaPIT, KodRSA, DefinicjaElementuRozliczenia
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
ListaPlac, Wyplata, WypElement, Zaliczka, KosztAutorski, ZaniechaniePodatkowe, OświadczenieZusOpieka, DodatekAutomatyczny, DefinicjaPlanowanejListyPłac, PlanowanaListaPłac, ZasiłekInnyPłatnik, DokumentRozliczeniaKontrahenta, DokumentRozliczeniaPracownika
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
KorektaDefElementu, CzasDefElementu, WspolczynnikDefElementu, KreatorAlgorytmu, AlgorytmDefElementu, KosztyUzyskaniaPrzychodu, ZaliczkaPodatku, UlgaPodatkowa, UbezpieczenieSpoleczne, UbezpieczenieZdrowotne, NarzutyNaWynagrodzenie, PodstawaUrlopu, PodstawaZasilkow, Zaokraglenie
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handel (Soneta.Handel)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefDokHandlowego, DefUrzadzeniaUz, DrukarkaFiskalna
|
||||||
|
|
||||||
|
**Tabele eksportowalne (guided=Exported):**
|
||||||
|
DokumentHandlowy, UrzadzenieUz
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
PrzesylkaSpedyt, PaczkaWzorcowa
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Realizacja, BruttoNetto, BruttoNettoCy, MozliwosciEdycji, Wersjonowanie, Przesylka, PunktOdbioru, EDokument, KreatorDokumentu, DokumentObcy, Wymiary
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Towary (Soneta.Towary)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
Jednostka, Przelicznik, DefinicjaCeny
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Towar, KodCN, KodBDO, KodCPV, KodSUP, SchemOpakowan, ElementKompletu, CenaGrupowa, PrzecenaOkresowa
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
GrupyDostawOpcje, AlgorytmCeny, AlgorytmRabatu, ProduktInfo, WspolczynnikCeny
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Magazyny (Soneta.Magazyny)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
Magazyn, OkresMagazynowy
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
PartiaTowaru, ParametryRezerwacji
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Kasa (Soneta.Kasa)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
FormatWymianyElektronicznej, SposobZaplaty, FormaPlatnosci, DefinicjaPaczkiPrzelewu, TypIdenPodPrzel, EwidencjaSP, OkresMW, SerwisBankowy
|
||||||
|
|
||||||
|
**Tabele eksportowalne (guided=Exported):**
|
||||||
|
Platnosc, DokKasowyBase
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
RachunekBankowyPodmiotu, Zaplata, RaportESP, RozliczenieSP, DokRozliczBase, PreliminarzDokument
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
NumerRachunku, RachunekBankowy, KartaPlatnicza, ElixirInfo, OdsetkiKarne
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Ksiega (Soneta.Ksiega)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
OkresObrachunkowy, DefinicjaSlownika, SchematKsiegowy, RelacjaOpisAnal, ZestawienieKS, MatrycaBase, DefinicjaKregu, ZnacznikKonta, GrupaKont, SchematPodz
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
DekretBase, KontoBase, ElemSlownika, WynikZestKS, SprawozdanieKS, ZleDlugiDokument
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
KPiR, DefinicjaZakresu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Waluty (Soneta.Waluty)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
Waluta, TabelaKursowa
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Euro
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SrodkiTrwale (Soneta.SrodkiTrwale)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
RodzajST, MiejsceUzytkowania, KategoriaST, KategoriaZapotrzebowania, TytulDokumentuST
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
SrodekTrwalyBase, DokumentST, DokumentUL, ZestawST, LokalizacjaNier, RodzajPO, Wyposazenie
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Sezonowosc, ParametryAmortyzacji
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### HR (Soneta.HR)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefElementuOcenyPracownika, WzorOcenyPracownika, DefinicjaStanowiska, DefinicjaFunkcji, DefinicjaEtapuRekrutacji, KategoriaUprawnienia, KategoriaSzkolenia, EtapRealizacjiSzkolenia, GrupaStanow
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
OcenaPracownika, Rekrutacja, EtapRekrutacji, Wyszukanie, DefinicjaUprawnienia, UprawnieniePracownika, DefinicjaSzkolenia, DostawcaSzkoleń, OfertaSzkolenia, BudżetSzkoleń, WniosekOSzkolenie, RealizacjaSzkolenia
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Oceny (Soneta.Oceny)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefinicjaSekcjiDokumentu, ZakresWartości, SkalaOcen, ElementSkaliOcen, KategoriaElementuOceny, DefinicjaElementuOceny, DefinicjaArkuszaOceny, DefinicjaOceny
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
OcenaRealizacja, OcenaArkusz, OcenaPowiaz
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
MiaraElementuOceny, WartośćElementuOceny
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Zadania (Soneta.Zadania)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DefKampania, DefProjektu, StanProjektu, DefZadania, StanZadania, PriorytetZadania, DefBudgetAspect, DefBudgetCategory, DefBudgetCategoryRelation, DefBudget, BudgetPeriod, DefPlanVersion, DefsKoresp, StanyKoresp, TypyUrzadzen, KategorieAkt, Zespoly
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Projekt, Zadanie, Kampania, WersjaPlanu, Urzadzenie, PlanowanyPrzeglad, Korespondencja, BudzetyProjektu, GoogleCalendars, ZadaniaDnia
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Budzet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Produkcja (Soneta.Produkcja)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
ProdProdukt, ProdSlownik
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Technologia, Operacja, PozycjaTechn, KosztTechn, CzasTechn, ProdZasob, ProdOsoba, ProdAwaria, ProdMeldunekBraku
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ProdukcjaPro (Soneta.ProdukcjaPro)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
ProWydzial, ProUzytkownikPaneluMeldunkowego
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
ProTechnologia, ProZlecenie, ProMeldunek, ProZasob, ProOsoba, ProStawka, ProDefinicjaMeldunku, ProKompetencja, ProDefinicjaOperacji, ProZestawienieMaterialow
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Support (Soneta.Support)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
TicketDefinition, Priority, State, Product, ProductVersion, OperatorToTeam, SLACalendar
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Ticket, Team, RelationToDoc, SLADocument, TicketFollower
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Vehicles (Soneta.Vehicles)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
VehicleType, VehicleState, ReservationDef, ReservationState
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
VehicleDetails, VehicleEvent, VehicleReading, Reservation, Fine, Insurance, DamageEvent, TechInspection, VehicleHis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Windykacja (Soneta.Windykacja)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
EtapDefinicjiWindykacji, DefinicjaSprawyWindykacyjnej, StanWindykacji
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
SprawaWindykacyjna
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
WindykacjaInfo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### RealEstate (Soneta.RealEstate)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
TypNieruchomosc, StanNieruchomosci, CelRezerwacji, DefinicjaAlgorytmuUslugi, DefinicjaRozliczeniaMediow
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Nieruchomosc, NieruchomoscHis, NieruchomoscZdarzenie, StanowiskoPracy, RezerwacjaStanowiskaPracy, UslugaNieruch, RozliczenieMediow
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
AlgorytmNieruchomosci, AlgorytmUslugi
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Delegacje (Soneta.Delegacje)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
KrajDelegacji, StawkiDelegacji
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Delegacja, KosztDelegacji
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Samochodowka (Soneta.Samochodowka)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
EkoRodzajPaliwa, EkoRodzajSilnika
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
Pojazd, DefinicjaTrasy, Przejazd, KosztEP, RozliczenieEP
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
Trasa
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### RMK (Soneta.RMK)
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
KosztRMK, DokumentRMK
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BI (Soneta.BI)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
DataSource, DataModel, ModelGroupBy, ModelOrderBy, TimeSpanDefinition, TimeSpanSet, TimeSpanItem, DashboardItemLocation, DashboardViewLocation, DashboardItemDefinition, ChartParam, DataSetDefinition, ColumnDefinition, SerializationDefinition, AnalysisArea
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
FieldProxy, TableProxy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Business (Soneta.Business.Db)
|
||||||
|
|
||||||
|
**Tabele konfiguracyjne (config=true):**
|
||||||
|
CfgNode, Operator, Entitle, DBItem, DBGroup, WizardDefinition, WizardStepDefinition, UserGroup, SysNotification, DashboardArea, DashboardView, SystemRole, RoleCategory, RuntimeSolution, RuntimeProject, PivotViews, NotifiCategories
|
||||||
|
|
||||||
|
**Tabele operacyjne (guided=Root):**
|
||||||
|
FeatureDefinition, FeatureTransferDefinition, FeatureSetDefinition, DictionaryItem, Task, SystemFiles, AppTokens
|
||||||
|
|
||||||
|
**Subrow:**
|
||||||
|
RuntimeDefinitionInfo, RuntimeFields, AlgorithmColumn
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
# Relacje między obiektami - Przewodnik
|
||||||
|
|
||||||
|
## Spis treści
|
||||||
|
|
||||||
|
1. [Typy relacji](#typy-relacji)
|
||||||
|
2. [Relacja jeden-do-wielu (master-detail)](#relacja-jeden-do-wielu)
|
||||||
|
3. [Relacja wiele-do-wielu](#relacja-wiele-do-wielu)
|
||||||
|
4. [Relacja do interfejsu](#relacja-do-interfejsu)
|
||||||
|
5. [Historia (wersjonowanie)](#historia-wersjonowanie)
|
||||||
|
6. [Relacja zwrotna (self-reference)](#relacja-zwrotna)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typy relacji
|
||||||
|
|
||||||
|
| Typ | Opis | W bazie danych | Przykład |
|
||||||
|
|-----|------|----------------|----------|
|
||||||
|
| Jeden-do-wielu | Dokument → Pozycje | FK (ID) | Faktura ma wiele pozycji |
|
||||||
|
| Wiele-do-wielu | Przez tabelę łączącą | 2x FK | Towar ↔ Kategorie |
|
||||||
|
| Interface'owa | Polimorficzna do wielu tabel | (tabela, ID) | IKontrahent → Osoba lub Firma |
|
||||||
|
| Historia | Wersjonowanie temporalne | FK + okres | Ceny towaru w czasie |
|
||||||
|
| Zwrotna | Do tej samej tabeli | FK (ID) | Kategoria nadrzędna |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relacja jeden-do-wielu
|
||||||
|
|
||||||
|
### Wzorzec: Dokument z pozycjami
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- TABELA NADRZĘDNA (master) -->
|
||||||
|
<table name="Dokument" tablename="Dokumenty" guided="Root">
|
||||||
|
<key name="WgNumeru" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Numer"/>
|
||||||
|
</key>
|
||||||
|
<col name="Numer" type="string" length="30" required="true"/>
|
||||||
|
<col name="Data" type="date" required="true"/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- TABELA PODRZĘDNA (detail) -->
|
||||||
|
<table name="PozycjaDokumentu" tablename="PozycjeDok">
|
||||||
|
<col name="Dokument" type="Dokument"
|
||||||
|
required="true"
|
||||||
|
readonly="true"
|
||||||
|
keyprimary="true"
|
||||||
|
children="Pozycje"
|
||||||
|
delete="cascade"
|
||||||
|
relguided="inner"
|
||||||
|
relname="Pozycje dokumentu"
|
||||||
|
description="Dokument, do którego należy pozycja"/>
|
||||||
|
<col name="Lp" type="int" required="true" batchfield="false"/>
|
||||||
|
<col name="Opis" type="string" length="200"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kluczowe atrybuty relacji podrzędnej
|
||||||
|
|
||||||
|
| Atrybut | Wartość | Znaczenie |
|
||||||
|
|---------|---------|-----------|
|
||||||
|
| `required="true"` | | Pozycja musi mieć dokument |
|
||||||
|
| `readonly="true"` | | Nie można przenosić między dokumentami |
|
||||||
|
| `keyprimary="true"` | | Klucz główny zaczyna się od dokumentu |
|
||||||
|
| `children="Pozycje"` | | Nazwa kolekcji w dokumencie: `dokument.Pozycje` |
|
||||||
|
| `delete="cascade"` | | Usunięcie dokumentu usuwa pozycje |
|
||||||
|
| `relguided="inner"` | | **Wymagane** dla tabel szczegółów (bez `guided`) |
|
||||||
|
|
||||||
|
### Zasada relguided="inner"
|
||||||
|
|
||||||
|
Tabele bez atrybutu `guided` (tabele szczegółów) **muszą mieć dokładnie jedną** relację z `relguided="inner"`. Wskazuje ona obiekt główny, którego szczegóły są opisywane.
|
||||||
|
|
||||||
|
### Klucz złożony z Lp
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Dokument" type="Dokument"
|
||||||
|
keyprimary="true" keyclass="Lp" keyclasscol="Lp"
|
||||||
|
children="Pozycje" delete="cascade">
|
||||||
|
<!-- keycol definiuje dodatkową kolumnę w kluczu -->
|
||||||
|
</col>
|
||||||
|
<col name="Lp" type="int" required="true"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relacja wiele-do-wielu
|
||||||
|
|
||||||
|
### Wzorzec: Tabela łącząca
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- TABELA ŁĄCZĄCA -->
|
||||||
|
<table name="TowarKategoria" tablename="TowaryKategorie">
|
||||||
|
<col name="Towar" type="Towar"
|
||||||
|
required="true"
|
||||||
|
keyprimary="true"
|
||||||
|
keyunique="true"
|
||||||
|
children="Kategorie"
|
||||||
|
delete="cascade"
|
||||||
|
relname="Kategorie towaru">
|
||||||
|
<keycol name="Kategoria"/>
|
||||||
|
</col>
|
||||||
|
<col name="Kategoria" type="Kategoria"
|
||||||
|
required="true"
|
||||||
|
children="Towary"
|
||||||
|
delete="cascade"
|
||||||
|
relname="Towary w kategorii">
|
||||||
|
<keycol name="Towar"/>
|
||||||
|
</col>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wzajemne keycol
|
||||||
|
|
||||||
|
Element `<keycol>` w kolumnie relacji tworzy indeks złożony:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Towar" type="Towar" keyunique="true">
|
||||||
|
<keycol name="Kategoria"/> <!-- Indeks: (Towar, Kategoria) -->
|
||||||
|
</col>
|
||||||
|
<col name="Kategoria" type="Kategoria">
|
||||||
|
<keycol name="Towar"/> <!-- Indeks: (Kategoria, Towar) -->
|
||||||
|
</col>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relacja do interfejsu (polimorficzna)
|
||||||
|
|
||||||
|
Relacja interface'owa pozwala na wskazanie obiektu z **dowolnej tabeli** implementującej dany interface. W bazie danych zapisywana jest para: `(nazwa_tabeli, ID)`.
|
||||||
|
|
||||||
|
### Deklaracja interfejsu
|
||||||
|
|
||||||
|
Interface musi być zadeklarowany w business.xml. Sama definicja interfejsu (metody, właściwości) jest w kodzie C#.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- DEKLARACJA INTERFEJSU w business.xml -->
|
||||||
|
<interface name="IKontrahent"/>
|
||||||
|
<interface name="IPodmiotKasowy"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wzorzec: Relacja interface'owa
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- TABELA Z RELACJĄ INTERFACE'OWĄ -->
|
||||||
|
<table name="Zamowienie" tablename="Zamowienia">
|
||||||
|
<!-- Typ to nazwa interfejsu - może wskazywać na Osobę, Firmę, lub inny obiekt implementujący IKontrahent -->
|
||||||
|
<col name="Kontrahent" type="IKontrahent"
|
||||||
|
required="true"
|
||||||
|
relname="Kontrahent zamówienia"
|
||||||
|
description="Może być osobą fizyczną lub firmą"/>
|
||||||
|
|
||||||
|
<!-- Relacja interface'owa do podmiotu kasowego -->
|
||||||
|
<col name="Platnik" type="IPodmiotKasowy"
|
||||||
|
relname="Płatnik zamówienia"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Różnica: relacja zwykła vs interface'owa
|
||||||
|
|
||||||
|
| Cecha | Relacja zwykła | Relacja interface'owa |
|
||||||
|
|-------|----------------|----------------------|
|
||||||
|
| Typ kolumny | `NazwaTabeli` | `INazwaInterface` |
|
||||||
|
| W bazie danych | tylko `ID` | `(nazwa_tabeli, ID)` |
|
||||||
|
| Wskazuje na | jedną konkretną tabelę | dowolną tabelę implementującą interface |
|
||||||
|
| Przykład | `type="Kontrahent"` | `type="IKontrahent"` |
|
||||||
|
|
||||||
|
### Popularne interfejsy enova365
|
||||||
|
|
||||||
|
| Interfejs | Opis |
|
||||||
|
|-----------|------|
|
||||||
|
| `IKontrahent` | Kontrahent (osoba/firma) |
|
||||||
|
| `IPodmiotKasowy` | Podmiot kasowy |
|
||||||
|
| `IRightsSource` | Źródło uprawnień |
|
||||||
|
| `IElementSlownika` | Element słownika |
|
||||||
|
| `IGuidedRow` | Wiersz z nawigacją |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Historia (wersjonowanie)
|
||||||
|
|
||||||
|
### Wzorzec: Dane historyczne
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="CenaHistoria" tablename="CenyHistoria">
|
||||||
|
<col name="Towar" type="Towar"
|
||||||
|
required="true"
|
||||||
|
readonly="true"
|
||||||
|
keyprimary="true"
|
||||||
|
keyclass="History"
|
||||||
|
keyclasscol="Okres"
|
||||||
|
children="HistoriaCen"
|
||||||
|
delete="cascade"
|
||||||
|
relguided="inner"
|
||||||
|
relname="Historia cen towaru"/>
|
||||||
|
<col name="Okres" type="FromTo" required="true"
|
||||||
|
caption="Okres obowiązywania"/>
|
||||||
|
<col name="CenaNetto" type="currency"/>
|
||||||
|
<col name="CenaBrutto" type="currency"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kluczowe atrybuty historii
|
||||||
|
|
||||||
|
| Atrybut | Wartość | Znaczenie |
|
||||||
|
|---------|---------|-----------|
|
||||||
|
| `keyclass="History"` | | Klasa indeksu historycznego |
|
||||||
|
| `keyclasscol="Okres"` | | Kolumna z okresem (FromTo) |
|
||||||
|
|
||||||
|
### Typ FromTo
|
||||||
|
|
||||||
|
Wbudowany typ dla okresów czasowych z polami `From` i `To`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relacja zwrotna
|
||||||
|
|
||||||
|
### Wzorzec: Struktura hierarchiczna
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Kategoria" tablename="Kategorie" guided="Root">
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
<col name="Kod" type="string" length="50" required="true"/>
|
||||||
|
<col name="Nazwa" type="string" length="100"/>
|
||||||
|
<col name="Nadrzedna" type="Kategoria"
|
||||||
|
children="Podkategorie"
|
||||||
|
relname="Kategoria nadrzędna"
|
||||||
|
description="Kategoria nadrzędna w hierarchii"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Z poziomem zagnieżdżenia
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Nadrzedna" type="Kategoria" children="Podkategorie">
|
||||||
|
<keycol name="Poziom"/>
|
||||||
|
</col>
|
||||||
|
<col name="Poziom" type="int" readonly="true"
|
||||||
|
description="Poziom w hierarchii (0 = root)"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wzorce złożone
|
||||||
|
|
||||||
|
### Relacja z dodatkowymi danymi
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="UdzialWProjekcie" tablename="UdzialyWProjektach">
|
||||||
|
<col name="Projekt" type="Projekt"
|
||||||
|
keyprimary="true" keyunique="true"
|
||||||
|
children="Udzialy" delete="cascade">
|
||||||
|
<keycol name="Pracownik"/>
|
||||||
|
</col>
|
||||||
|
<col name="Pracownik" type="Pracownik"
|
||||||
|
required="true"
|
||||||
|
children="Projekty" delete="cascade">
|
||||||
|
<keycol name="Projekt"/>
|
||||||
|
</col>
|
||||||
|
<!-- Dodatkowe dane relacji -->
|
||||||
|
<col name="Rola" type="RolaWProjekcie"/>
|
||||||
|
<col name="OdKiedy" type="date"/>
|
||||||
|
<col name="DoKiedy" type="date"/>
|
||||||
|
<col name="Stawka" type="currency"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Relacja z kaskadowym usuwaniem warunkowym
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Kontrahent" type="Kontrahent"
|
||||||
|
delete="cascade"
|
||||||
|
children="Dokumenty"
|
||||||
|
relname="Dokumenty kontrahenta">
|
||||||
|
<!-- Weryfikator sprawdza warunki przed usunięciem -->
|
||||||
|
<verifier name="Dokument.KontrahentDeleteVerifier"/>
|
||||||
|
</col>
|
||||||
|
```
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
# Table Reference - Kompletna dokumentacja
|
||||||
|
|
||||||
|
## Spis treści
|
||||||
|
|
||||||
|
1. [Atrybuty table](#atrybuty-table)
|
||||||
|
2. [Atrybuty col](#atrybuty-col)
|
||||||
|
3. [Element key](#element-key)
|
||||||
|
4. [Element verifier](#element-verifier)
|
||||||
|
5. [Element attribute](#element-attribute)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Atrybuty table
|
||||||
|
|
||||||
|
| Atrybut | Wymagany | Typ | Opis |
|
||||||
|
|---------|----------|-----|------|
|
||||||
|
| `name` | ✓ | string | Nazwa klasy C# (PascalCase, l.poj.) |
|
||||||
|
| `tablename` | ✓ | string | Nazwa tabeli w bazie (PascalCase, l.mn.) |
|
||||||
|
| `guided` | | string | `Root` = główna tabela (dokument, kartoteka) |
|
||||||
|
| `config` | | boolean | `true` = tabela konfiguracyjna (wdrożeniowa) |
|
||||||
|
| `caption` | | string | Etykieta pojedynczego rekordu |
|
||||||
|
| `tablecaption` | | string | Etykieta listy rekordów |
|
||||||
|
| `namespace` | | string | Nadpisuje namespace z modułu |
|
||||||
|
| `name8` | | string | Skrócona nazwa (max 8 znaków, legacy) |
|
||||||
|
| `cached` | | boolean | `true` = cache'owanie w pamięci |
|
||||||
|
| `timestamp` | | boolean | `true` = automatyczne pole timestamp |
|
||||||
|
| `optimisticlocking` | | boolean | `true` = optymistyczne blokowanie |
|
||||||
|
| `lock` | | string | Tryb blokowania |
|
||||||
|
| `warnings` | | string | `Off` = wyłącza ostrzeżenia |
|
||||||
|
|
||||||
|
### Rodzaje tabel
|
||||||
|
|
||||||
|
**`guided="Root"`** - Główne tabele programu:
|
||||||
|
- Dokumenty, kartoteki (towar, pracownik, kontrahent)
|
||||||
|
- Dostępne z menu głównego
|
||||||
|
|
||||||
|
**`guided="Exported"`** - Tabele eksportowalne:
|
||||||
|
- Jak Root, ale z możliwością eksportu do systemów zewnętrznych
|
||||||
|
- Najważniejsze tabele transakcyjne (DokumentHandlowy, Platnosc)
|
||||||
|
- Używaj dla dokumentów wymagających integracji
|
||||||
|
|
||||||
|
**Bez `guided`** - Tabele szczegółów:
|
||||||
|
- Pozycje dokumentu, kody towaru, adresy
|
||||||
|
- Muszą mieć dokładnie jedną relację `relguided="inner"`
|
||||||
|
|
||||||
|
**`config="true"`** - Tabele konfiguracyjne:
|
||||||
|
- Dane wdrożeniowe: definicje, słowniki, ustawienia
|
||||||
|
- Konfiguracja algorytmów, formularzy, wydruków
|
||||||
|
|
||||||
|
**Bez `config`** - Tabele operacyjne:
|
||||||
|
- Dane zbierane podczas pracy: dokumenty, transakcje
|
||||||
|
|
||||||
|
### Przykład table z wszystkimi atrybutami
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Towar"
|
||||||
|
tablename="Towary"
|
||||||
|
name8="Towar"
|
||||||
|
guided="Root"
|
||||||
|
config="false"
|
||||||
|
caption="Towar"
|
||||||
|
tablecaption="Towary"
|
||||||
|
cached="false"
|
||||||
|
timestamp="false"
|
||||||
|
optimisticlocking="true">
|
||||||
|
<!-- zawartość -->
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Atrybuty col
|
||||||
|
|
||||||
|
### Podstawowe
|
||||||
|
|
||||||
|
| Atrybut | Wymagany | Typ | Opis |
|
||||||
|
|---------|----------|-----|------|
|
||||||
|
| `name` | ✓ | string | Nazwa właściwości C# |
|
||||||
|
| `type` | ✓ | string | Typ danych (patrz typy) |
|
||||||
|
| `length` | dla string | uint/max | Długość tekstu lub `"max"` dla nieograniczonej |
|
||||||
|
| `required` | | RequiredType | `true`/`false`/`noverified` |
|
||||||
|
| `readonly` | | ReadonlyType | `true`/`false`/`set` |
|
||||||
|
| `caption` | | string | Etykieta pola w UI |
|
||||||
|
| `description` | | string | Jedno/dwuzdaniowy opis pola (tooltip) |
|
||||||
|
| `category` | | string | Kategoria w edytorze właściwości |
|
||||||
|
|
||||||
|
### Ograniczenia typów
|
||||||
|
|
||||||
|
- **`text`** i **`binary`** - nie mogą być kluczami (`keyprimary`, `keyunique`)
|
||||||
|
- **`string length="max"`** - tekst bez ograniczenia, wczytywany z rekordem
|
||||||
|
- **`text`** - wczytywany na żądanie (osobne zapytanie SQL)
|
||||||
|
|
||||||
|
### Modyfikatory
|
||||||
|
|
||||||
|
| Atrybut | Typ | Opis |
|
||||||
|
|---------|-----|------|
|
||||||
|
| `modifier` | string | Modyfikator C#: `public virtual`, `protected`, `internal` |
|
||||||
|
| `important` | boolean | `true` = pole wyświetlane na liście |
|
||||||
|
| `selector` | boolean | `true` = pole selektor typu |
|
||||||
|
| `batchfield` | boolean | `false` = pomijane przy batch operations |
|
||||||
|
| `fulltext` | boolean | `true` = indeksowanie pełnotekstowe |
|
||||||
|
| `specialaccess` | boolean | `true` = specjalne uprawnienia |
|
||||||
|
|
||||||
|
### Relacje
|
||||||
|
|
||||||
|
| Atrybut | Typ | Opis |
|
||||||
|
|---------|-----|------|
|
||||||
|
| `children` | string | Nazwa kolekcji dzieci w obiekcie nadrzędnym |
|
||||||
|
| `relname` | string | Opis relacji |
|
||||||
|
| `relguided` | string | `inner` = nawigacja wewnętrzna |
|
||||||
|
| `relright` | boolean | `true` = prawa do relacji |
|
||||||
|
| `reldefault` | boolean | `true` = domyślna relacja |
|
||||||
|
| `delete` | string | Akcja przy usuwaniu: `cascade`, `setnull` |
|
||||||
|
| `setonlynull` | boolean | `true` = można ustawić tylko raz |
|
||||||
|
|
||||||
|
### Indeksy (inline w col)
|
||||||
|
|
||||||
|
| Atrybut | Typ | Opis |
|
||||||
|
|---------|-----|------|
|
||||||
|
| `keyprimary` | boolean | `true` = część klucza głównego |
|
||||||
|
| `keyunique` | boolean | `true` = wartość unikalna |
|
||||||
|
| `keyclass` | string | Klasa indeksu: `History`, `Lp` |
|
||||||
|
| `keyclasscol` | string | Kolumna dla keyclass |
|
||||||
|
|
||||||
|
### Lokalizacja
|
||||||
|
|
||||||
|
| Atrybut | Typ | Opis |
|
||||||
|
|---------|-----|------|
|
||||||
|
| `localization` | LocalizationType | `none`/`dictionary`/`db` |
|
||||||
|
| `name12` | string | Skrócona nazwa kolumny (max 12 zn.) |
|
||||||
|
| `cstype` | string | Nadpisanie typu C# |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RequiredType - wartości
|
||||||
|
|
||||||
|
- `true` - pole wymagane, walidowane
|
||||||
|
- `false` - pole opcjonalne
|
||||||
|
- `noverified` - pole wymagane, ale bez walidacji
|
||||||
|
|
||||||
|
## ReadonlyType - wartości
|
||||||
|
|
||||||
|
- `true` - tylko do odczytu
|
||||||
|
- `false` - edytowalne
|
||||||
|
- `set` - można ustawić tylko przy tworzeniu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Element key
|
||||||
|
|
||||||
|
Definiuje indeks na tabeli.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="WgKontrahentaIDaty" keyunique="false">
|
||||||
|
<keycol name="Kontrahent"/>
|
||||||
|
<keycol name="Data"/>
|
||||||
|
</key>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Atrybuty key
|
||||||
|
|
||||||
|
| Atrybut | Typ | Opis |
|
||||||
|
|---------|-----|------|
|
||||||
|
| `name` | string | Nazwa indeksu (konwencja: `Wg` + kolumny) |
|
||||||
|
| `keyunique` | boolean | `true` = indeks unikalny |
|
||||||
|
| `keyprimary` | boolean | `true` = klucz główny |
|
||||||
|
| `keyclass` | string | Klasa indeksu |
|
||||||
|
| `keyclasscol` | string | Kolumna dla klasy |
|
||||||
|
| `lock` | string | Tryb blokowania: `ExclusiveGet` |
|
||||||
|
|
||||||
|
### Element keycol
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<keycol name="NazwaKolumny"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Element keyinclude
|
||||||
|
|
||||||
|
Dodatkowe kolumny w indeksie (INCLUDE w SQL):
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<key name="WgKodu">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
<keyinclude name="Nazwa"/>
|
||||||
|
</key>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Element verifier
|
||||||
|
|
||||||
|
Walidator pola wywoływany przy zapisie.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="Nazwa" type="string" length="100">
|
||||||
|
<verifier name="Towar.NazwaVerifier"/>
|
||||||
|
<verifier name="Towar.NazwaUniqueVerifier" onadded="true"/>
|
||||||
|
</col>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Atrybuty verifier
|
||||||
|
|
||||||
|
| Atrybut | Wymagany | Typ | Opis |
|
||||||
|
|---------|----------|-----|------|
|
||||||
|
| `name` | ✓ | string | Pełna nazwa klasy weryfikatora |
|
||||||
|
| `onadded` | | boolean | `true` = tylko przy dodawaniu |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Element attribute
|
||||||
|
|
||||||
|
Atrybut C# dodawany do właściwości.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<col name="KodPocztowy" type="int">
|
||||||
|
<attribute>MaskEdit("00-000", SaveLiteral=false)</attribute>
|
||||||
|
<attribute>Browsable(false)</attribute>
|
||||||
|
<attribute>Dictionary("Miejscowość")</attribute>
|
||||||
|
<attribute>Obsolete("Użyj pola X")</attribute>
|
||||||
|
<attribute>Context</attribute>
|
||||||
|
<attribute>Context(Required=false)</attribute>
|
||||||
|
</col>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Popularne atrybuty
|
||||||
|
|
||||||
|
| Atrybut | Opis |
|
||||||
|
|---------|------|
|
||||||
|
| `Browsable(false)` | Ukrywa pole w UI |
|
||||||
|
| `Context` | Pole kontekstowe |
|
||||||
|
| `Context(Required=false)` | Opcjonalny kontekst |
|
||||||
|
| `Dictionary("nazwa")` | Słownik podpowiedzi |
|
||||||
|
| `MaskEdit("maska")` | Maska wprowadzania |
|
||||||
|
| `Obsolete("msg")` | Oznacza jako przestarzałe |
|
||||||
|
| `NumeratorItem` | Element numeratora |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Przykład kompletnej tabeli
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="Faktura" tablename="Faktury" guided="Root"
|
||||||
|
caption="Faktura" tablecaption="Faktury">
|
||||||
|
|
||||||
|
<interface>IRightsSource</interface>
|
||||||
|
<interface>IDefinicjaDokumentuOA</interface>
|
||||||
|
|
||||||
|
<key name="WgNumeru" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Numer"/>
|
||||||
|
</key>
|
||||||
|
<key name="WgKontrahenta">
|
||||||
|
<keycol name="Kontrahent"/>
|
||||||
|
<keycol name="Data"/>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<col name="Numer" type="string" length="30" required="true"
|
||||||
|
category="Ogólne" important="true"
|
||||||
|
description="Numer dokumentu"/>
|
||||||
|
|
||||||
|
<col name="Data" type="date" required="true"
|
||||||
|
category="Ogólne"
|
||||||
|
description="Data wystawienia">
|
||||||
|
<verifier name="Faktura.DataVerifier"/>
|
||||||
|
</col>
|
||||||
|
|
||||||
|
<col name="Kontrahent" type="Kontrahent" required="true"
|
||||||
|
category="Ogólne"
|
||||||
|
relname="Kontrahent faktury"
|
||||||
|
children="Faktury">
|
||||||
|
<attribute>Context</attribute>
|
||||||
|
</col>
|
||||||
|
|
||||||
|
<col name="Status" type="StatusFaktury"
|
||||||
|
category="Ogólne" selector="true"
|
||||||
|
description="Status dokumentu"/>
|
||||||
|
|
||||||
|
<col name="WartoscNetto" type="currency" readonly="true"
|
||||||
|
category="Wartości" caption="Wartość netto"/>
|
||||||
|
|
||||||
|
<col name="WartoscBrutto" type="currency" readonly="true"
|
||||||
|
category="Wartości" caption="Wartość brutto"/>
|
||||||
|
|
||||||
|
<col name="Uwagi" type="text" category="Dodatkowe"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
@@ -0,0 +1,351 @@
|
|||||||
|
---
|
||||||
|
name: soneta-programming-basics
|
||||||
|
description: >
|
||||||
|
Fundamentalne klasy ORM platformy enova365/Soneta Enterprise. Obejmuje mapowanie
|
||||||
|
obiektowo-relacyjne (Row, Table, Module), zarządzanie sesją (Session), logowanie
|
||||||
|
(Login, Database, BusApplication), paczki danych (Datapack, GuidedRow) oraz
|
||||||
|
kontekst (Context). Używaj gdy użytkownik pyta o podstawowe klasy logiki biznesowej,
|
||||||
|
strukturę obiektów ORM, sesje i transakcje, hierarchię klas Row/Table/Module,
|
||||||
|
mechanizm Datapack i synchronizację danych, lub kontekst aplikacji enova365.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Soneta Programming Basics - Podstawowe klasy ORM
|
||||||
|
|
||||||
|
Skill zawiera dokumentację fundamentalnych klas logiki biznesowej platformy enova365/Soneta Enterprise. Klasy te stanowią podstawę mapowania obiektowo-relacyjnego (ORM) i są niezbędne do tworzenia dodatków.
|
||||||
|
|
||||||
|
## Architektura warstw
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ Interfejs graficzny (UI) │
|
||||||
|
├─────────────────────────────────────────────────────┤
|
||||||
|
│ Context │ ← Komunikacja UI ↔ logika
|
||||||
|
├─────────────────────────────────────────────────────┤
|
||||||
|
│ Logika biznesowa │
|
||||||
|
│ ┌─────────────────────────────────────────────┐ │
|
||||||
|
│ │ BusApplication (Singleton) │ │
|
||||||
|
│ │ └── Database (konfiguracja bazy) │ │
|
||||||
|
│ │ └── Login (uwierzytelnienie) │ │
|
||||||
|
│ │ └── Session (zarządzanie danymi) │ │
|
||||||
|
│ │ └── Module → Table → Row │ │
|
||||||
|
│ └─────────────────────────────────────────────┘ │
|
||||||
|
├─────────────────────────────────────────────────────┤
|
||||||
|
│ Baza danych SQL │
|
||||||
|
└─────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3 poziomy logiki biznesowej
|
||||||
|
|
||||||
|
| Poziom | Opis | Przykłady klas |
|
||||||
|
|--------|------|----------------|
|
||||||
|
| **1. Bazowe** | Klasy wspólne dla wszystkich modułów (Soneta.Business.dll) | `Row`, `Table`, `Module`, `Session`, `Context` |
|
||||||
|
| **2. Generowane** | Klasy generowane przez BusinessGenerator z *.business.xml (sufiksy: Row, Table, Module) | `TowarRow`, `TowarTable`, `TowaryModule` |
|
||||||
|
| **3. Implementowane** | Klasy konkretne tworzone przez programistę | `Towar`, `Towary` (bez sufiksów) |
|
||||||
|
|
||||||
|
**BusinessGenerator** jest automatycznie uruchamiany podczas kompilacji dla plików `*.business.xml`. Szczegółowy opis definiowania business.xml znajduje się w skill **soneta-business-xml**.
|
||||||
|
|
||||||
|
## Hierarchia głównych klas
|
||||||
|
|
||||||
|
```
|
||||||
|
Row (abstrakcyjna)
|
||||||
|
└── GuidedRow (+ Guid, Attachments, ChangeInfos)
|
||||||
|
└── ExportedRow (+ Exported flag)
|
||||||
|
|
||||||
|
Table (abstrakcyjna)
|
||||||
|
└── GuidedTable (indeksator po Guid)
|
||||||
|
└── ExportedTable
|
||||||
|
|
||||||
|
Module (abstrakcyjna)
|
||||||
|
└── [NazwaModulu]Module (np. TowaryModule)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Thread-safety
|
||||||
|
|
||||||
|
### Obiekty single-threaded (NIE współdzielić między wątkami)
|
||||||
|
- `Session`
|
||||||
|
- `Module`
|
||||||
|
- `Table`
|
||||||
|
- `Row`
|
||||||
|
- `Context`
|
||||||
|
- oraz wszystkie klasy pochodne
|
||||||
|
|
||||||
|
Każdy wątek powinien tworzyć własną sesję.
|
||||||
|
|
||||||
|
### Obiekty multi-threaded (można współdzielić)
|
||||||
|
- `BusApplication`
|
||||||
|
- `Database`
|
||||||
|
- `Login`
|
||||||
|
|
||||||
|
## Klasa Session - fundamenty
|
||||||
|
|
||||||
|
Session to kluczowa klasa do zarządzania danymi. **Każda operacja na danych wymaga sesji.**
|
||||||
|
|
||||||
|
### Tworzenie sesji
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Przez Login
|
||||||
|
Session session = login.CreateSession(readOnly: false, config: false, name: "MojaSesja");
|
||||||
|
|
||||||
|
// Parametry konstruktora:
|
||||||
|
// readOnly: true = tylko odczyt, false = edycja
|
||||||
|
// config: true = dane konfiguracyjne (cache), false = dane operacyjne (aktualne)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typy sesji
|
||||||
|
|
||||||
|
| Typ | ReadOnly | Config | Użycie |
|
||||||
|
|-----|----------|--------|--------|
|
||||||
|
| Edycyjna operacyjna | false | false | Modyfikacja dokumentów, kartotek |
|
||||||
|
| ReadOnly operacyjna | true | false | Odczyt danych transakcyjnych |
|
||||||
|
| Edycyjna konfiguracyjna | false | true | Modyfikacja ustawień |
|
||||||
|
| ReadOnly konfiguracyjna | true | true | Odczyt konfiguracji |
|
||||||
|
|
||||||
|
**WAŻNE:** W sesji operacyjnej nie można modyfikować obiektów konfiguracyjnych - wymagana jest sesja konfiguracyjna (`config: true`).
|
||||||
|
|
||||||
|
### Transakcje biznesowe (WAŻNE!)
|
||||||
|
|
||||||
|
**Każda zmiana obiektu MUSI być w transakcji biznesowej** otwieranej przez `Session.Logout(editMode: true)`:
|
||||||
|
- Dodawanie nowych obiektów
|
||||||
|
- Modyfikacja właściwości (properties)
|
||||||
|
- Kasowanie obiektów
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Logout(editMode: true) - transakcja edycyjna (można modyfikować)
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
towar.Nazwa = "Zmieniona nazwa";
|
||||||
|
transaction.Commit(); // lub CommitUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logout(editMode: false) - transakcja tylko do odczytu
|
||||||
|
// (modyfikacje możliwe tylko w zagnieżdżonej transakcji edycyjnej)
|
||||||
|
using (var readTransaction = session.Logout(editMode: false))
|
||||||
|
{
|
||||||
|
// odczyt danych...
|
||||||
|
|
||||||
|
// zagnieżdżona transakcja edycyjna
|
||||||
|
using (var editTransaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var cena = towar.Ceny["Hurtowa"];
|
||||||
|
cena.Netto = new DoubleCy(100m);
|
||||||
|
editTransaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
readTransaction.Commit(); // WYMAGANE! Inaczej zmiany z zagnieżdżonych transakcji przepadną
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Brak Commit() = automatyczny rollback przy Dispose()** (dotyczy też transakcji tylko do odczytu!)
|
||||||
|
|
||||||
|
### Optimistic locking
|
||||||
|
|
||||||
|
Zmiany wykonywane są w trybie **optimistic-lock**:
|
||||||
|
- Zmiany kumulują się w sesji
|
||||||
|
- `Session.Save()` zapisuje wszystkie zmiany razem
|
||||||
|
- Konflikty wykrywane w momencie zapisu
|
||||||
|
|
||||||
|
### Ważne zasady
|
||||||
|
|
||||||
|
- Session implementuje `IDisposable` - **zawsze wywołuj Dispose()** lub używaj `using`
|
||||||
|
- Wiele sesji może współistnieć jednocześnie
|
||||||
|
- Sesja konfiguracyjna używa cache'a (optymalizacja odczytów)
|
||||||
|
- Sesja operacyjna zawsze czyta z bazy (aktualność danych)
|
||||||
|
- **Nie mieszaj obiektów z różnych sesji** - użyj `session.Get(obiekt)` aby doczytać obiekt w bieżącej sesji
|
||||||
|
|
||||||
|
## Klasa Module
|
||||||
|
|
||||||
|
Moduł grupuje logicznie powiązane tabele. **Nie ma odwzorowania w bazie danych.**
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Dostęp do modułu - extension method (zalecane)
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var hm = session.GetHandel();
|
||||||
|
var crm = session.GetCRM();
|
||||||
|
var bm = session.GetBusiness();
|
||||||
|
|
||||||
|
// Dostęp do tabel
|
||||||
|
Towary towary = tm.Towary;
|
||||||
|
Jednostki jednostki = tm.Jednostki;
|
||||||
|
|
||||||
|
// Moduł implementuje ISessionable
|
||||||
|
Session s = tm.Session;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Klasa Table
|
||||||
|
|
||||||
|
Reprezentuje tabelę w bazie danych. Udostępnia dostęp do kolekcji wierszy.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var towary = tm.Towary;
|
||||||
|
|
||||||
|
// Iteracja po kluczu podstawowym
|
||||||
|
foreach (Towar t in towary.WgKodu) { ... }
|
||||||
|
|
||||||
|
// Iteracja po innym kluczu
|
||||||
|
foreach (Towar t in towary.WgNazwy) { ... }
|
||||||
|
|
||||||
|
// Właściwości
|
||||||
|
Table.AccessRight // Prawa dostępu
|
||||||
|
Table.Session // Sesja (ISessionable)
|
||||||
|
Table.Module // Moduł nadrzędny
|
||||||
|
Table.PrimaryKey // Klucz podstawowy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Klasa Row
|
||||||
|
|
||||||
|
Reprezentuje pojedynczy wiersz (rekord) z tabeli.
|
||||||
|
|
||||||
|
### Właściwości bazowe
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
Row.ID // int - PODSTAWOWY identyfikator obiektu w tabeli (autoincrement, Primary Key)
|
||||||
|
Row.State // RowState - stan obiektu w sesji
|
||||||
|
Row.Table // Table - tabela nadrzędna
|
||||||
|
Row.Module // Module - moduł
|
||||||
|
Row.Session // Session - sesja
|
||||||
|
```
|
||||||
|
|
||||||
|
**ID** jest automatycznie generowany przez bazę danych i stanowi klucz główny (Primary Key) tabeli.
|
||||||
|
|
||||||
|
### Stany obiektu (RowState)
|
||||||
|
|
||||||
|
| Stan | Opis |
|
||||||
|
|------|------|
|
||||||
|
| `Detached` | Nowy obiekt, nie przypisany do tabeli |
|
||||||
|
| `Unchanged` | Wczytany z bazy, bez zmian |
|
||||||
|
| `Modified` | Zmodyfikowany w sesji |
|
||||||
|
| `Added` | Nowy, dodany do tabeli, nie zapisany w bazie |
|
||||||
|
| `Deleted` | Skasowany, do usunięcia z bazy |
|
||||||
|
|
||||||
|
## Klucze i indeksy
|
||||||
|
|
||||||
|
Definiowane w *.business.xml, mapowane na indeksy w bazie danych.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<key name="WgKodu" keyunique="true" keyprimary="true">
|
||||||
|
<keycol name="Kod"/>
|
||||||
|
</key>
|
||||||
|
```
|
||||||
|
|
||||||
|
| Atrybut | Znaczenie |
|
||||||
|
|---------|-----------|
|
||||||
|
| `keyprimary="true"` | Klucz podstawowy (domyślne sortowanie) |
|
||||||
|
| `keyunique="true"` | Wartości unikalne w tabeli |
|
||||||
|
|
||||||
|
**Uwaga:** `keyprimary` w business.xml to **nie to samo** co Primary Key w bazie (który jest zawsze na kolumnie ID).
|
||||||
|
|
||||||
|
## Interfejs ISessionable
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public interface ISessionable {
|
||||||
|
Session Session { get; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Implementują go: `Session`, `Module`, `Table`, `Row`, `Context`, `Key`.
|
||||||
|
|
||||||
|
Używany jako argument funkcji wymagających kontekstu sesji:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Metoda statyczna GetInstance - akceptuje ISessionable
|
||||||
|
public static TowaryModule GetInstance(ISessionable session)
|
||||||
|
|
||||||
|
// Extension method - wygodniejsza składnia (tylko dla Session)
|
||||||
|
public static TowaryModule GetTowary(this Session session)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Zalecane użycie:**
|
||||||
|
```csharp
|
||||||
|
// Extension method (prostsze)
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
// GetInstance (gdy mamy ISessionable, np. Row lub Context)
|
||||||
|
var tm = TowaryModule.GetInstance(context);
|
||||||
|
var tm = TowaryModule.GetInstance(towar); // towar implementuje ISessionable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Szczegółowa dokumentacja
|
||||||
|
|
||||||
|
- **[references/session-login.md](references/session-login.md)** - BusApplication, Database, Login, Session
|
||||||
|
- **[references/datapack-guidedrow.md](references/datapack-guidedrow.md)** - Paczki danych, GuidedRow, ExportedRow, synchronizacja
|
||||||
|
- **[references/context.md](references/context.md)** - Klasa Context, komunikacja UI ↔ logika
|
||||||
|
- **[references/examples.md](references/examples.md)** - Przykłady kodu i wzorce użycia
|
||||||
|
|
||||||
|
## Szybki start - wzorce kodu
|
||||||
|
|
||||||
|
### Odczyt danych
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var session = login.CreateSession(true, false, "Odczyt"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary(); // Extension method
|
||||||
|
foreach (Towar t in tm.Towary.WgKodu)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{t.Kod}: {t.Nazwa}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tworzenie nowego obiektu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var session = login.CreateSession(false, false, "Dodawanie"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var towar = new Towar();
|
||||||
|
tm.Towary.AddRow(towar);
|
||||||
|
towar.Kod = "NOWY001";
|
||||||
|
towar.Nazwa = "Nowy towar";
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modyfikacja istniejącego obiektu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var session = login.CreateSession(false, false, "Edycja"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var towar = tm.Towary.WgKodu["STARY001"];
|
||||||
|
if (towar != null)
|
||||||
|
{
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
towar.Nazwa = "Zmieniona nazwa";
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Konwencje nazewnicze
|
||||||
|
|
||||||
|
| Element | Konwencja | Przykład |
|
||||||
|
|---------|-----------|----------|
|
||||||
|
| Klasa wiersza (Row) | PascalCase, l.poj. | `Towar`, `Kontrahent` |
|
||||||
|
| Klasa tabeli | PascalCase, l.mn. | `Towary`, `Kontrahenci` |
|
||||||
|
| Klasa modułu | Nazwa + Module | `TowaryModule` |
|
||||||
|
| Klucz | Wg + nazwa kolumny | `WgKodu`, `WgNazwy` |
|
||||||
|
| Namespace | Soneta.NazwaModułu | `Soneta.Towary` |
|
||||||
|
|
||||||
|
### Język identyfikatorów
|
||||||
|
|
||||||
|
| Typ | Język | Przykłady |
|
||||||
|
|-----|-------|-----------|
|
||||||
|
| Logika biznesowa | **polski** | `Towar`, `Kontrahent`, `DokumentHandlowy`, `Faktura` |
|
||||||
|
| Identyfikatory systemowe | **angielski** | `Session`, `Context`, `Row`, `Table`, `Module` |
|
||||||
|
|
||||||
|
**Można łączyć polski i angielski** w nazwach metod i klas:
|
||||||
|
```csharp
|
||||||
|
RetrieveTowary()
|
||||||
|
UpdateKontrahent()
|
||||||
|
GetDokumentyHandlowe()
|
||||||
|
CreateFaktura()
|
||||||
|
```
|
||||||
@@ -0,0 +1,334 @@
|
|||||||
|
# Klasa Context
|
||||||
|
|
||||||
|
Dokumentacja klasy Context odpowiedzialnej za komunikację między warstwą logiki biznesowej a interfejsem graficznym.
|
||||||
|
|
||||||
|
## Czym jest Context?
|
||||||
|
|
||||||
|
Context to **kontener par klucz-wartość**, gdzie:
|
||||||
|
- **Klucz** = typ (Type)
|
||||||
|
- **Wartość** = obiekt tego typu (object)
|
||||||
|
|
||||||
|
Kontekst jest stale aktualizowany podczas pracy z programem i przechowuje informacje o aktualnym stanie interfejsu.
|
||||||
|
|
||||||
|
## Zawartość kontekstu
|
||||||
|
|
||||||
|
Przykładowa zawartość przy otwartej liście kontrahentów:
|
||||||
|
|
||||||
|
| Typ | Opis |
|
||||||
|
|-----|------|
|
||||||
|
| `SelectedCounter` | Liczba zaznaczonych wierszy na gridzie |
|
||||||
|
| `Kontrahent[]` | Kolekcja zaznaczonych kontrahentów |
|
||||||
|
| `UILocation` | Aktywny element interfejsu |
|
||||||
|
| `INavigatorContext` | Kontekst grida (zaznaczenia, focus) |
|
||||||
|
| `View` | Źródło danych grida |
|
||||||
|
| `Params` | Klasa parametrów filtrów |
|
||||||
|
| `LicencjaProgramu` | Informacje o licencji |
|
||||||
|
| `Login` | Zalogowany użytkownik |
|
||||||
|
| `MsSqlDatabase` | Baza danych |
|
||||||
|
|
||||||
|
## Odczyt z kontekstu
|
||||||
|
|
||||||
|
### Metody GetOrDefault i GetRequired (zalecane)
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context context)
|
||||||
|
{
|
||||||
|
// Zwraca obiekt lub null, gdy brak obiektu
|
||||||
|
Kontrahent? knt = context.GetOrDefault<Kontrahent>();
|
||||||
|
|
||||||
|
// Zwraca obiekt lub wyjątek, gdy brak obiektu
|
||||||
|
Kontrahent knt2 = context.GetRequired<Kontrahent>();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Przez indeksator (rzuca wyjątek gdy brak)
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
// Rzuca wyjątek gdy brak obiektu w kontekście
|
||||||
|
Kontrahent knt = (Kontrahent)cx[typeof(Kontrahent)];
|
||||||
|
|
||||||
|
// Bez wyjątku - drugi parametr
|
||||||
|
Kontrahent knt2 = (Kontrahent)cx[typeof(Kontrahent), false];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Przez metodę Get<T> (bezpieczna)
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
// Zwraca true jeśli znaleziono, false jeśli nie
|
||||||
|
if (cx.Get(out DokumentHandlowy dokument))
|
||||||
|
{
|
||||||
|
// dokument znaleziony
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// dokument nie znaleziony (dokument = null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Zapis do kontekstu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
// Przez indeksator
|
||||||
|
Kontrahent knt = ...;
|
||||||
|
cx[typeof(Kontrahent)] = knt;
|
||||||
|
|
||||||
|
// Przez metodę Set
|
||||||
|
DokumentHandlowy dok = ...;
|
||||||
|
cx.Set(dok);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Zastosowania
|
||||||
|
|
||||||
|
### 1. Filtry na listach głównych
|
||||||
|
|
||||||
|
Klasy parametrów filtrów dziedziczą z `ContextBase` i są automatycznie w kontekście.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Definicja klasy parametrów (w ViewInfo)
|
||||||
|
public class TowaryParams(Context context) : ContextBase(context)
|
||||||
|
{
|
||||||
|
public Magazyn? Magazyn
|
||||||
|
{
|
||||||
|
get => Context.GetOrDefault<Magazyn>();
|
||||||
|
set => Context.Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypTowaru Typ {
|
||||||
|
get => Context.GetOrDefault<TypTowaru>();
|
||||||
|
set => Context.Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Accessor(AutoChange = true)]
|
||||||
|
public string SearchString { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Bindowanie w viewform.xml -->
|
||||||
|
<Field CaptionHtml="Magazyn" EditValue="{TowaryParams.Magazyn}"/>
|
||||||
|
<Field CaptionHtml="Typ" EditValue="{TowaryParams.Typ}"/>
|
||||||
|
<Field CaptionHtml="Szukaj" EditValue="{TowaryParams.SearchString}"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Wartości filtrów są dostępne przez kontekst dla:
|
||||||
|
- Widoków (filtrowanie danych)
|
||||||
|
- Workerów (właściwości wyliczane)
|
||||||
|
- Wydruków
|
||||||
|
|
||||||
|
### 2. Wartości domyślne nowych obiektów
|
||||||
|
|
||||||
|
Kontekst używany do inicjalizacji nowych obiektów wartościami z filtrów. Uzupełniane są właściwości zaznaczone atrybutem `[Context]`, który oznacza próbę odczytania wartości do ustawienia property z kontekstu.
|
||||||
|
|
||||||
|
```
|
||||||
|
Lista faktur:
|
||||||
|
Filtr Magazyn: "Sklep"
|
||||||
|
Filtr Kontrahent: "Drynda"
|
||||||
|
↓
|
||||||
|
Nowy dokument:
|
||||||
|
Magazyn: "Sklep" (z kontekstu - property z [Context])
|
||||||
|
Kontrahent: "Drynda" (z kontekstu - property z [Context])
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Wydruki
|
||||||
|
|
||||||
|
Wydruki mają dostęp do obiektów z kontekstu jako źródła danych.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// W kodzie wydruku
|
||||||
|
Context cx = ...;
|
||||||
|
if (cx.Get(out Kontrahent[] kontrahenci))
|
||||||
|
{
|
||||||
|
// kontrahenci[] = zaznaczone na liście
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Workery - atrybut [Context]
|
||||||
|
|
||||||
|
Workery mogą pobierać parametry z kontekstu automatycznie.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class MojWorker
|
||||||
|
{
|
||||||
|
[Context] // Pobierane z kontekstu
|
||||||
|
public Magazyn Magazyn { get; set; }
|
||||||
|
|
||||||
|
[Context] // Jeśli brak w kontekście - okno parametrów
|
||||||
|
public Kontrahent Kontrahent { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Właściwości wyliczane zależne od filtrów
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Worker wyliczający stan magazynowy
|
||||||
|
public class StanMagazynu : IWorker
|
||||||
|
{
|
||||||
|
public object Compute(Context cx, object source)
|
||||||
|
{
|
||||||
|
Towar towar = source as Towar;
|
||||||
|
|
||||||
|
// Pobranie magazynu z kontekstu (z filtra)
|
||||||
|
if (cx.Get(out Magazyn magazyn))
|
||||||
|
{
|
||||||
|
return towar.GetStan(magazyn);
|
||||||
|
}
|
||||||
|
return towar.GetStanCalkowity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Klasa ContextBase
|
||||||
|
|
||||||
|
Bazowa klasa dla obiektów automatycznie umieszczanych w kontekście.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class MojaKlasaParametrow(Context context) : ContextBase(context)
|
||||||
|
{
|
||||||
|
[Accessor(AutoChange = true)]
|
||||||
|
public Date DataOd { get; set; }
|
||||||
|
|
||||||
|
[Accessor(AutoChange = true)]
|
||||||
|
public Date DataDo { get; set; }
|
||||||
|
|
||||||
|
public Kontrahent Kontrahent {
|
||||||
|
get => Context.GetOrDefault<Kontrahent>();
|
||||||
|
set => Context.Set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Obiekty dziedziczące z `ContextBase` i nie tylko:
|
||||||
|
- Są automatycznie dodawane do kontekstu
|
||||||
|
- Wywoływane jest zdarzenie `OnChanged` przy zmianie właściwości
|
||||||
|
- Obsługują bindowanie do kontrolek UI
|
||||||
|
- Właściwości połączone z UI (formularze, parametry) mogą być zadeklarowane z `[Accessor(AutoChange = true)]`, dzięki czemu Accessor automatycznie uruchomi mechanizm powiadamiania o zmianach i nie będzie konieczne wywołanie `Session.InvokeChanged()` lub `Context.InvokeChanged()`
|
||||||
|
|
||||||
|
## Interfejs INavigatorContext
|
||||||
|
|
||||||
|
Dostępny w kontekście gdy aktywna jest lista (grid).
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
if (cx.Get(out INavigatorContext nav))
|
||||||
|
{
|
||||||
|
// Wiersz z focusem
|
||||||
|
object current = nav.Current;
|
||||||
|
|
||||||
|
// Zaznaczone wiersze
|
||||||
|
IEnumerable selected = nav.Selected;
|
||||||
|
|
||||||
|
// Liczba zaznaczonych
|
||||||
|
int count = nav.SelectedCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kolekcje zaznaczonych obiektów
|
||||||
|
|
||||||
|
W kontekście znajdują się tablice zaznaczonych obiektów.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
// Zaznaczeni kontrahenci
|
||||||
|
if (cx.Get(out Kontrahent[] kontrahenci))
|
||||||
|
{
|
||||||
|
foreach (var k in kontrahenci)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zaznaczone dokumenty
|
||||||
|
if (cx.Get(out DokumentHandlowy[] dokumenty))
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Context implementuje ISessionable
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void Action(Context cx)
|
||||||
|
{
|
||||||
|
// Dostęp do sesji przez kontekst
|
||||||
|
Session session = cx.Session;
|
||||||
|
|
||||||
|
// Dostęp do modułu przez sesję
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pełny przykład - Worker z kontekstem
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[assembly: Worker<TowarExtender, Towar>]
|
||||||
|
|
||||||
|
namespace Soneta.Towary;
|
||||||
|
|
||||||
|
public class TowarExtenderParams(Context context) : ContextBase(context)
|
||||||
|
{
|
||||||
|
[Accessor(AutoChange = true)]
|
||||||
|
[Caption("Magazyn filtrowania")]
|
||||||
|
public Magazyn MagazynFiltra { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TowarExtender
|
||||||
|
{
|
||||||
|
[Context]
|
||||||
|
public TowarExtenderParams Params { get; set; }
|
||||||
|
|
||||||
|
[Context]
|
||||||
|
public Towar Towar { get; set; }
|
||||||
|
|
||||||
|
public decimal StanWMagazynie =>
|
||||||
|
Params.MagazynFiltra != null
|
||||||
|
? PoliczStanMagazynu(Towar, Params.MagazynFiltra)
|
||||||
|
: PoliczStanMagazynu(Towar);
|
||||||
|
|
||||||
|
private decimal PoliczStanMagazynu(Towar towar, Magazyn magazyn)
|
||||||
|
{
|
||||||
|
// Wyliczyć stan we wskazanym magazynie
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private decimal PoliczStanMagazynu(Towar towar)
|
||||||
|
{
|
||||||
|
// Wyliczyć stan w całej firmie
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dobre praktyki
|
||||||
|
|
||||||
|
1. **Używaj Get<T>, GetOrDefault<T>, GetRequired<T>** zamiast indeksatora - bezpieczniejsze
|
||||||
|
2. **Sprawdzaj obecność** obiektów w kontekście przed użyciem
|
||||||
|
3. **Dziedzicz z ContextBase** dla własnych klas parametrów i pamiętaj o konstruktorze `(Context context)`
|
||||||
|
4. **Używaj [Context]** w workerach dla parametrów z kontekstu
|
||||||
|
5. **Stosuj `[Accessor(AutoChange = true)]`** lub `InvokeChanged()` dla powiadamiania UI o zmianach
|
||||||
|
|
||||||
|
## Typowe typy w kontekście
|
||||||
|
|
||||||
|
| Typ | Kiedy dostępny |
|
||||||
|
|-----|----------------|
|
||||||
|
| `Login` | Zawsze po zalogowaniu |
|
||||||
|
| `Database` | Zawsze po zalogowaniu |
|
||||||
|
| `LicencjaProgramu` | Zawsze po zalogowaniu |
|
||||||
|
| `Session` | Gdy aktywny widok z danymi |
|
||||||
|
| `View` | Gdy aktywna lista |
|
||||||
|
| `INavigatorContext` | Gdy aktywna lista |
|
||||||
|
| `[Obiekt][]` | Zaznaczenia na liście |
|
||||||
|
| `[ViewInfo]+Params` | Klasa parametrów widoku |
|
||||||
|
| `UILocation` | Lokalizacja w UI |
|
||||||
@@ -0,0 +1,245 @@
|
|||||||
|
# Datapack i GuidedRow - Paczki danych
|
||||||
|
|
||||||
|
Dokumentacja mechanizmu paczek danych (Datapack) służącego do grupowania powiązanych obiektów i ich synchronizacji między bazami danych.
|
||||||
|
|
||||||
|
## Czym jest Datapack?
|
||||||
|
|
||||||
|
**Datapack** to struktura obiektów różnych typów powiązanych relacjami, które tworzą logiczną całość.
|
||||||
|
|
||||||
|
### Przykład: Dokument handlowy
|
||||||
|
|
||||||
|
```
|
||||||
|
DokumentHandlowy (Root)
|
||||||
|
├── PozycjaDokHandlowego[] (Child)
|
||||||
|
├── SumaVAT[] (Child)
|
||||||
|
└── Platnosc[] (Child)
|
||||||
|
```
|
||||||
|
|
||||||
|
Faktura bez pozycji nie jest kompletną fakturą - wszystkie te obiekty stanowią jedną paczkę danych.
|
||||||
|
|
||||||
|
## Hierarchia klas Row i Table
|
||||||
|
|
||||||
|
```
|
||||||
|
Row (abstrakcyjna) Table (abstrakcyjna)
|
||||||
|
│ └── ID: int └── GuidedTable (indeksator po Guid)
|
||||||
|
│ └── State: RowState └── ExportedTable
|
||||||
|
│
|
||||||
|
└── GuidedRow
|
||||||
|
│ └── Guid: System.Guid
|
||||||
|
│ └── Attachments
|
||||||
|
│ └── FirstChangeInfo, LastChangeInfo
|
||||||
|
│ └── Note
|
||||||
|
│
|
||||||
|
└── ExportedRow
|
||||||
|
└── Exported: bool
|
||||||
|
```
|
||||||
|
|
||||||
|
## Atrybut guided w business.xml
|
||||||
|
|
||||||
|
Atrybut `guided` w definicji tabeli określa rolę obiektu w strukturze Datapack.
|
||||||
|
|
||||||
|
| Wartość | Klasa bazowa | Opis |
|
||||||
|
|---------|--------------|------|
|
||||||
|
| `Root` | `GuidedRow` | Główny element paczki danych. Posiada GUID. |
|
||||||
|
| `Exported` | `ExportedRow` | Jak Root + flaga Exported (czy wyeksportowany) |
|
||||||
|
| `Child` | `Row` | Element podrzędny w paczce. Musi mieć relację `relguided`. |
|
||||||
|
| `None` | `Row` | Nie uczestniczy w mechanizmie Datapack |
|
||||||
|
|
||||||
|
**Domyślnie:** `guided="Child"`
|
||||||
|
|
||||||
|
### Przykłady definicji
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- ROOT - główna kartoteka towaru -->
|
||||||
|
<table name="Towar" tablename="Towary" guided="Root">
|
||||||
|
...
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- EXPORTED - dokument do synchronizacji -->
|
||||||
|
<table name="DokumentHandlowy" tablename="DokHandlowe" guided="Exported">
|
||||||
|
...
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- CHILD - pozycje dokumentu (domyślnie) -->
|
||||||
|
<table name="PozycjaDokHandlowego" tablename="PozycjeDokHan">
|
||||||
|
<col name="Dokument" type="DokumentHandlowy"
|
||||||
|
relguided="inner" delete="cascade"
|
||||||
|
children="Pozycje"/>
|
||||||
|
...
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Atrybut relguided
|
||||||
|
|
||||||
|
Określa relację obiektu Child do obiektu Root w strukturze Datapack.
|
||||||
|
|
||||||
|
| Wartość | Opis |
|
||||||
|
|---------|------|
|
||||||
|
| `inner` | Obiekt podrzędny zagnieżdżony wewnątrz roota w XML |
|
||||||
|
| `outer` | Obiekt podrzędny poza rootem w XML (ale powiązany) |
|
||||||
|
| (puste) | Relacja nie jest częścią Datapack |
|
||||||
|
|
||||||
|
### Kiedy używać relguided
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Pozycja dokumentu - CZĘŚĆ datapacka dokumentu -->
|
||||||
|
<col name="Dokument" type="DokumentHandlowy"
|
||||||
|
relguided="inner" <!-- ← powiązanie w Datapack -->
|
||||||
|
delete="cascade"
|
||||||
|
children="Pozycje"/>
|
||||||
|
|
||||||
|
<!-- Towar na pozycji - NIE jest częścią datapacka dokumentu -->
|
||||||
|
<col name="Towar" type="Towar" <!-- ← brak relguided -->
|
||||||
|
children="Pozycje"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reguły:**
|
||||||
|
- Tabela Child może mieć **tylko jedną** kolumnę z `relguided`
|
||||||
|
- Tabela Root **nie posiada** relacji `relguided` (jest korzeniem paczki)
|
||||||
|
|
||||||
|
## GuidedRow - szczegóły
|
||||||
|
|
||||||
|
### Właściwości
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `Guid` | `System.Guid` | Globalnie unikalny identyfikator |
|
||||||
|
| `Attachments` | `AttachmentCollection` | Kolekcja załączników |
|
||||||
|
| `DefaultImage` | `Attachment` | Domyślne zdjęcie obiektu |
|
||||||
|
| `Note` | `string` | Notatka tekstowa |
|
||||||
|
| `FirstChangeInfo` | `ChangeInfo` | Pierwsza zmiana w historii |
|
||||||
|
| `LastChangeInfo` | `ChangeInfo` | Ostatnia zmiana w historii |
|
||||||
|
| `IsAdded` | `bool` | Czy nowo dodany |
|
||||||
|
| `IsModified` | `bool` | Czy zmodyfikowany |
|
||||||
|
| `IsDeleted` | `bool` | Czy skasowany |
|
||||||
|
|
||||||
|
### Załączniki
|
||||||
|
|
||||||
|
Załączniki można podpinać **tylko** do obiektów wywodzących się z `GuidedRow`.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
GuidedRow row = ...;
|
||||||
|
|
||||||
|
// Dostęp do załączników
|
||||||
|
foreach (Attachment att in row.Attachments)
|
||||||
|
{
|
||||||
|
Console.WriteLine(att.Nazwa);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Domyślne zdjęcie
|
||||||
|
Attachment img = row.DefaultImage;
|
||||||
|
```
|
||||||
|
|
||||||
|
## ExportedRow
|
||||||
|
|
||||||
|
Rozszerza `GuidedRow` o flagę `Exported`.
|
||||||
|
|
||||||
|
### Użycie
|
||||||
|
|
||||||
|
Obiekty, które po eksporcie do systemów zewnętrznych **nie powinny być modyfikowane**.
|
||||||
|
|
||||||
|
**Przykład:** Przelew wyeksportowany do systemu bankowego - po zaksięgowaniu nie powinien być zmieniany w ERP.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<table name="PrzelewBase" tablename="Przelewy" guided="Exported">
|
||||||
|
...
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Właściwość
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `Exported` | `bool` | `true` = obiekt wyeksportowany, nie modyfikować |
|
||||||
|
|
||||||
|
## Historia zmian (ChangeInfos)
|
||||||
|
|
||||||
|
System loguje zmiany na obiektach `GuidedRow`.
|
||||||
|
|
||||||
|
### Tabela ChangeInfos
|
||||||
|
|
||||||
|
| Kolumna | Opis |
|
||||||
|
|---------|------|
|
||||||
|
| `SourceTable` | Nazwa tabeli źródłowej |
|
||||||
|
| `SourceGuid` | GUID zmodyfikowanego obiektu |
|
||||||
|
| `Time` | Data i czas zmiany |
|
||||||
|
| `Operator` | Kto dokonał zmiany |
|
||||||
|
|
||||||
|
### Dostęp do historii
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var bm = session.GetBusiness();
|
||||||
|
|
||||||
|
// Iteracja po historii zmian kontrahenta
|
||||||
|
Kontrahent knt = ...;
|
||||||
|
foreach (ChangeInfo ci in bm.ChangeInfos[knt])
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{ci.Time}: {ci.Operator}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skróty na obiekcie
|
||||||
|
Console.WriteLine($"Utworzono: {knt.FirstChangeInfo?.Time}");
|
||||||
|
Console.WriteLine($"Ostatnia zmiana: {knt.LastChangeInfo?.Time}");
|
||||||
|
```
|
||||||
|
|
||||||
|
**Uwaga:** Zmiany na obiektach Child są rejestrowane na poziomie Root.
|
||||||
|
|
||||||
|
## Blokady
|
||||||
|
|
||||||
|
Modyfikacja **dowolnego** obiektu w strukturze Datapack zakłada blokadę na poziomie **Root**.
|
||||||
|
|
||||||
|
```
|
||||||
|
DokumentHandlowy ← BLOKADA
|
||||||
|
├── PozycjaDokHandlowego (modyfikacja tutaj)
|
||||||
|
└── SumaVAT
|
||||||
|
```
|
||||||
|
|
||||||
|
Nie można równolegle edytować obiektów należących do jednego Datapacka.
|
||||||
|
|
||||||
|
## GuidedTable
|
||||||
|
|
||||||
|
Odpowiednik `GuidedRow` dla tabel - dodaje indeksator po GUID.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
GuidedTable<Towar> towary = ...;
|
||||||
|
|
||||||
|
// Pobranie obiektu po GUID
|
||||||
|
Guid guid = new Guid("65336878-70cf-4e64-bd72-b742cd26a657");
|
||||||
|
Towar towar = towary[guid];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wzorce użycia
|
||||||
|
|
||||||
|
### Definiowanie struktury Datapack
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- 1. Root - główny obiekt -->
|
||||||
|
<table name="Zamowienie" tablename="Zamowienia" guided="Root">
|
||||||
|
<key name="WgNumeru" keyprimary="true" keyunique="true">
|
||||||
|
<keycol name="Numer"/>
|
||||||
|
</key>
|
||||||
|
<col name="Numer" type="string" length="30" required="true"/>
|
||||||
|
<col name="Data" type="date" required="true"/>
|
||||||
|
<col name="Kontrahent" type="Kontrahent" required="true"/>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- 2. Child - pozycje zamówienia -->
|
||||||
|
<table name="PozycjaZamowienia" tablename="PozycjeZamowien">
|
||||||
|
<!-- Jedna relacja relguided="inner" -->
|
||||||
|
<col name="Zamowienie" type="Zamowienie"
|
||||||
|
required="true" readonly="true"
|
||||||
|
relguided="inner" delete="cascade"
|
||||||
|
children="Pozycje" keyprimary="true"/>
|
||||||
|
<col name="Lp" type="int" required="true"/>
|
||||||
|
<col name="Towar" type="Towar" required="true"/>
|
||||||
|
<col name="Ilosc" type="double" required="true"/>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Podsumowanie atrybutów
|
||||||
|
|
||||||
|
| Atrybut | Gdzie | Wartości | Opis |
|
||||||
|
|---------|-------|----------|------|
|
||||||
|
| `guided` | `<table>` | Root, Exported, Child, None | Rola w Datapack |
|
||||||
|
| `relguided` | `<col>` | inner, outer, (puste) | Relacja Child→Root |
|
||||||
|
| `delete` | `<col>` | cascade, restrict, setnull | Akcja przy usuwaniu roota |
|
||||||
@@ -0,0 +1,643 @@
|
|||||||
|
# Przykłady kodu - Podstawowe klasy ORM
|
||||||
|
|
||||||
|
Praktyczne przykłady użycia podstawowych klas logiki biznesowej enova365/Soneta.
|
||||||
|
|
||||||
|
## Ważne zasady
|
||||||
|
|
||||||
|
### Thread-safety
|
||||||
|
|
||||||
|
**Obiekty single-threaded** - nie współdziel między wątkami:
|
||||||
|
- `Session`, `Module`, `Table`, `Row`, `Context`
|
||||||
|
|
||||||
|
**Obiekty multi-threaded** - można współdzielić:
|
||||||
|
- `BusApplication`, `Database`, `Login`
|
||||||
|
|
||||||
|
Każdy wątek powinien tworzyć własną sesję (Login można współdzielić).
|
||||||
|
|
||||||
|
### Extension methods dla modułów
|
||||||
|
|
||||||
|
Dostęp do modułów przez extension methods:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var hm = session.GetHandel();
|
||||||
|
var crm = session.GetCRM();
|
||||||
|
var kadry = session.GetKadry();
|
||||||
|
var bm = session.GetBusiness();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transakcje biznesowe
|
||||||
|
|
||||||
|
**Każda zmiana obiektu MUSI być w transakcji** `Session.Logout(editMode: true)`:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
// Zmiany: dodawanie, modyfikacja, kasowanie
|
||||||
|
obiekt.Wlasciwosc = nowaWartosc;
|
||||||
|
transaction.Commit(); // Zatwierdza zmiany
|
||||||
|
}
|
||||||
|
// Brak Commit() = automatyczny rollback
|
||||||
|
|
||||||
|
session.Save(); // Zapis do bazy danych
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dostęp do danych
|
||||||
|
|
||||||
|
### Odczyt listy towarów
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Soneta.Business;
|
||||||
|
using Soneta.Towary;
|
||||||
|
|
||||||
|
public void WyswietlTowary(Login login)
|
||||||
|
{
|
||||||
|
// Sesja tylko do odczytu
|
||||||
|
using (var session = login.CreateSession(true, false, "OdczytTowarow"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary(); // Extension method
|
||||||
|
|
||||||
|
// Iteracja po kluczu podstawowym (WgKodu)
|
||||||
|
foreach (Towar t in tm.Towary.WgKodu)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{t.Kod}: {t.Nazwa}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wyszukiwanie po kluczu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public Towar ZnajdzTowar(Session session, string kod)
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
// Wyszukiwanie po kluczu unikalnym
|
||||||
|
return tm.Towary.WgKodu[kod];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Iteracja z filtrowaniem
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void WyswietlAktywneTowary(Session session)
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
foreach (Towar t in tm.Towary.WgKodu)
|
||||||
|
{
|
||||||
|
// Filtrowanie w kodzie
|
||||||
|
if (t.Typ == TypTowaru.Towar)
|
||||||
|
{
|
||||||
|
Console.WriteLine(t.Nazwa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tworzenie obiektów
|
||||||
|
|
||||||
|
### Dodawanie nowego towaru
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void DodajTowar(Login login)
|
||||||
|
{
|
||||||
|
// Sesja edycyjna
|
||||||
|
using (var session = login.CreateSession(false, false, "DodawanieTowaru"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
// Transakcja biznesowa - wymagana!
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
// Utworzenie nowego obiektu
|
||||||
|
var towar = new Towar();
|
||||||
|
|
||||||
|
// Dodanie do tabeli (zmiana stanu na Added)
|
||||||
|
tm.Towary.AddRow(towar);
|
||||||
|
|
||||||
|
// Ustawienie właściwości
|
||||||
|
towar.Kod = "NOWY001";
|
||||||
|
towar.Nazwa = "Nowy towar";
|
||||||
|
towar.Typ = TypTowaru.Towar;
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zapisanie do bazy
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dodawanie dokumentu z pozycjami
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void UtworzFakture(Login login, Kontrahent kontrahentZInnejSesji,
|
||||||
|
List<(Towar towar, int ilosc)> pozycjeZInnejSesji)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "TworzenieFaktury"))
|
||||||
|
{
|
||||||
|
var hm = session.GetHandel();
|
||||||
|
|
||||||
|
// WAŻNE: Obiekty z innej sesji trzeba doczytać w bieżącej sesji!
|
||||||
|
var kontrahent = session.Get(kontrahentZInnejSesji);
|
||||||
|
|
||||||
|
// Cała operacja w jednej transakcji
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
// Utworzenie nagłówka dokumentu
|
||||||
|
var faktura = new DokumentHandlowy();
|
||||||
|
hm.DokHandlowe.AddRow(faktura);
|
||||||
|
|
||||||
|
faktura.Definicja = hm.DefDokHandlowe.WgSymbolu["FV"];
|
||||||
|
faktura.Kontrahent = kontrahent;
|
||||||
|
faktura.Data = Date.Today;
|
||||||
|
|
||||||
|
// Dodanie pozycji
|
||||||
|
int lp = 1;
|
||||||
|
foreach (var (towarZInnejSesji, ilosc) in pozycjeZInnejSesji)
|
||||||
|
{
|
||||||
|
// Doczytaj towar w bieżącej sesji
|
||||||
|
var towar = session.Get(towarZInnejSesji);
|
||||||
|
|
||||||
|
var poz = new PozycjaDokHandlowego(faktura);
|
||||||
|
faktura.Pozycje.AddRow(poz);
|
||||||
|
|
||||||
|
poz.Towar = towar;
|
||||||
|
poz.Ilosc = new Quantity(ilosc, towar.Jednostka.Kod);
|
||||||
|
poz.Lp = lp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**WAŻNE:** W jednej sesji nie można mieszać obiektów z różnych sesji. Użyj `session.Get(obiekt)` aby doczytać obiekt w bieżącej sesji.
|
||||||
|
|
||||||
|
## Modyfikacja obiektów
|
||||||
|
|
||||||
|
### Aktualizacja pojedynczego obiektu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void ZmienNazweTowaru(Login login, string kod, string nowaNazwa)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "EdycjaTowaru"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var towar = tm.Towary.WgKodu[kod];
|
||||||
|
|
||||||
|
if (towar != null)
|
||||||
|
{
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
towar.Nazwa = nowaNazwa;
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aktualizacja z transakcją biznesową
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void AktualizujCeny(Login login, string nazwaCeny, decimal procentPodwyzki)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "AktualizacjaCen"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
foreach (Towar t in tm.Towary.WgKodu)
|
||||||
|
{
|
||||||
|
// Transakcja biznesowa - WYMAGANA dla każdej zmiany!
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var cena = t.Ceny[nazwaCeny];
|
||||||
|
if (cena != null)
|
||||||
|
{
|
||||||
|
cena.Netto = new DoubleCy(cena.Netto.Value * (1 + procentPodwyzki / 100));
|
||||||
|
}
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save(); // Zapisuje wszystkie zmiany do bazy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usuwanie obiektów
|
||||||
|
|
||||||
|
### Usuwanie obiektu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void UsunTowar(Login login, string kod)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "UsuwanieTowaru"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var towar = tm.Towary.WgKodu[kod];
|
||||||
|
|
||||||
|
if (towar != null)
|
||||||
|
{
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
towar.Delete(); // Zmiana stanu na Deleted
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
session.Save(); // Fizyczne usunięcie z bazy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Praca z kontekstem
|
||||||
|
|
||||||
|
### Worker wyliczający właściwość
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Rejestracja workera na poziomie assembly
|
||||||
|
[assembly: Worker<TowarWorker, Towar>]
|
||||||
|
|
||||||
|
public class TowarWorker
|
||||||
|
{
|
||||||
|
[Context]
|
||||||
|
public Magazyn MagazynFiltra { get; set; }
|
||||||
|
|
||||||
|
[Context]
|
||||||
|
public Towar Towar { get; set; }
|
||||||
|
|
||||||
|
public decimal StanMagazynowy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (MagazynFiltra != null)
|
||||||
|
{
|
||||||
|
return PoliczStan(Towar, MagazynFiltra);
|
||||||
|
}
|
||||||
|
return PoliczStanCalkowity(Towar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private decimal PoliczStan(Towar towar, Magazyn magazyn)
|
||||||
|
{
|
||||||
|
// Implementacja...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private decimal PoliczStanCalkowity(Towar towar)
|
||||||
|
{
|
||||||
|
// Implementacja...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Akcja workera w menu Czynności
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Rejestracja workera na poziomie assembly
|
||||||
|
[assembly: Worker<WyslijEmailWorker, Kontrahent>]
|
||||||
|
|
||||||
|
public class WyslijEmailWorker
|
||||||
|
{
|
||||||
|
[Context]
|
||||||
|
public Kontrahent[] Kontrahenci { get; set; }
|
||||||
|
|
||||||
|
[Context]
|
||||||
|
public Context Context { get; set; }
|
||||||
|
|
||||||
|
[Action("Wyślij email")]
|
||||||
|
public void Execute()
|
||||||
|
{
|
||||||
|
foreach (var k in Kontrahenci)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(k.Email))
|
||||||
|
{
|
||||||
|
WyslijEmail(k.Email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WyslijEmail(string email)
|
||||||
|
{
|
||||||
|
// Implementacja...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Klasa parametrów (ContextBase)
|
||||||
|
|
||||||
|
Klasa `ContextBase` jest przeznaczona do budowania klas parametrów, nie workerów:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class FiltryTowarow(Context context) : ContextBase(context)
|
||||||
|
{
|
||||||
|
public Magazyn Magazyn { get; set; }
|
||||||
|
|
||||||
|
[Caption("Typ towaru")] // Etykieta w UI, gdy inna niż nazwa property
|
||||||
|
public TypTowaru? Typ { get; set; }
|
||||||
|
|
||||||
|
public bool TylkoAktywne { get; set; } = true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Uwaga:** W klasach parametrów atrybut `[Context]` nie jest wymagany.
|
||||||
|
|
||||||
|
**Współdzielenie wartości przez Context** - wartości parametrów można przechowywać w obiekcie Context, co pozwala na współdzielenie między różnymi klasami parametrów:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class FiltryTowarow(Context context) : ContextBase(context)
|
||||||
|
{
|
||||||
|
public Magazyn Magazyn
|
||||||
|
{
|
||||||
|
get => Context.GetOrDefault<Magazyn>();
|
||||||
|
set => Context.Set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Caption("Typ towaru")]
|
||||||
|
public TypTowaru? Typ
|
||||||
|
{
|
||||||
|
get => Context.GetOrDefault<TypTowaru?>();
|
||||||
|
set => Context.Set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Praca z GuidedRow
|
||||||
|
|
||||||
|
### Dostęp do historii zmian
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void PokazHistorie(Session session, Kontrahent kontrahent)
|
||||||
|
{
|
||||||
|
var bm = session.GetBusiness();
|
||||||
|
|
||||||
|
Console.WriteLine($"Historia zmian dla: {kontrahent.Nazwa}");
|
||||||
|
|
||||||
|
foreach (ChangeInfo ci in bm.ChangeInfos[kontrahent])
|
||||||
|
{
|
||||||
|
Console.WriteLine($" {ci.Time}: {ci.Operator}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skróty
|
||||||
|
Console.WriteLine($"Utworzono: {kontrahent.FirstChangeInfo?.Time}");
|
||||||
|
Console.WriteLine($"Ostatnia zmiana: {kontrahent.LastChangeInfo?.Time}");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Praca z załącznikami
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void DodajZalacznik(Login login, Towar towar, byte[] plik, string nazwa)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "DodawanieZalacznika"))
|
||||||
|
{
|
||||||
|
// Doczytaj towar w bieżącej sesji
|
||||||
|
var towarInSession = session.Get(towar);
|
||||||
|
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var attachment = new Attachment(towarInSession, AttachmentType.Attachments);
|
||||||
|
towarInSession.Module.Business.Attachments.AddRow(attachment);
|
||||||
|
|
||||||
|
attachment.Name = nazwa;
|
||||||
|
attachment.RawData = plik;
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WyswietlZalaczniki(Towar towar)
|
||||||
|
{
|
||||||
|
foreach (Attachment att in towar.Attachments)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"- {att.Name} ({att.RawData.Length} bajtów)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Domyślne zdjęcie
|
||||||
|
using var defaultImage = towar.DefaultImage;
|
||||||
|
if (defaultImage != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Zdjęcie główne: {defaultImage.FileName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dane konfiguracyjne vs operacyjne
|
||||||
|
|
||||||
|
### Odczyt danych konfiguracyjnych
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Odczyt pojedynczej wartości
|
||||||
|
var opisDlaSzt = login.ExecuteConfig(configSession =>
|
||||||
|
configSession.GetTowary().Jednostki.WgKodu["szt"]?.Opis);
|
||||||
|
|
||||||
|
// Odczyt listy wartości prostych
|
||||||
|
public string[] PobierzKodyJednostek(Login login)
|
||||||
|
{
|
||||||
|
return login.ExecuteConfig(configSession =>
|
||||||
|
{
|
||||||
|
var tm = configSession.GetTowary();
|
||||||
|
return tm.Jednostki.WgKodu.Select(j => j.Kod).ToArray();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**WAŻNE:** Używając `ExecuteConfig()` nie można zwracać obiektów sesyjnych z sesji konfiguracyjnej, ponieważ może być używana w innym wątku do innych celów. Zwracaj tylko wartości proste lub kopie danych.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void OdczytKonfiguracji(Login login)
|
||||||
|
{
|
||||||
|
// Własna sesja konfiguracyjna - gdy potrzebny dostęp do obiektów
|
||||||
|
using (var session = login.CreateSession(true, true, "Konfiguracja"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
foreach (Jednostka j in tm.Jednostki.WgKodu)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{j.Kod}: {j.Opis}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modyfikacja danych konfiguracyjnych
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void DodajJednostke(Login login, string kod, string opis)
|
||||||
|
{
|
||||||
|
// Sesja edycyjna konfiguracyjna
|
||||||
|
using (var session = login.CreateSession(false, true, "DodawanieJednostki"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var jednostka = new Jednostka();
|
||||||
|
tm.Jednostki.AddRow(jednostka);
|
||||||
|
|
||||||
|
jednostka.Kod = kod;
|
||||||
|
jednostka.Opis = opis;
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pełny przykład - import towarów
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class ImportTowarow
|
||||||
|
{
|
||||||
|
public void Importuj(Login login, string sciezkaPliku)
|
||||||
|
{
|
||||||
|
var dane = WczytajZPliku(sciezkaPliku);
|
||||||
|
|
||||||
|
using (var session = login.CreateSession(false, false, "ImportTowarow"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
int dodano = 0;
|
||||||
|
int zaktualizowano = 0;
|
||||||
|
|
||||||
|
// Cały import w jednej transakcji
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
foreach (var wiersz in dane)
|
||||||
|
{
|
||||||
|
// Sprawdź czy towar istnieje
|
||||||
|
var towar = tm.Towary.WgKodu[wiersz.Kod];
|
||||||
|
|
||||||
|
if (towar == null)
|
||||||
|
{
|
||||||
|
// Dodaj nowy
|
||||||
|
towar = new Towar();
|
||||||
|
tm.Towary.AddRow(towar);
|
||||||
|
towar.Kod = wiersz.Kod;
|
||||||
|
dodano++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zaktualizowano++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ustaw/aktualizuj właściwości
|
||||||
|
towar.Nazwa = wiersz.Nazwa;
|
||||||
|
var cena = towar.Ceny["Hurtowa"];
|
||||||
|
cena.Netto = new DoubleCy(wiersz.Cena);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save();
|
||||||
|
|
||||||
|
Console.WriteLine($"Import zakończony:");
|
||||||
|
Console.WriteLine($" Dodano: {dodano}");
|
||||||
|
Console.WriteLine($" Zaktualizowano: {zaktualizowano}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DaneImportu> WczytajZPliku(string sciezka)
|
||||||
|
{
|
||||||
|
// Implementacja wczytywania z CSV/Excel...
|
||||||
|
return new List<DaneImportu>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DaneImportu
|
||||||
|
{
|
||||||
|
public string Kod { get; set; }
|
||||||
|
public string Nazwa { get; set; }
|
||||||
|
public decimal Cena { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Obsługa błędów
|
||||||
|
|
||||||
|
### Wzorzec try-catch z sesją
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void BezpiecznaOperacja(Login login)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "Operacja"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
// Operacje na danych...
|
||||||
|
var towar = new Towar();
|
||||||
|
tm.Towary.AddRow(towar);
|
||||||
|
towar.Kod = "TEST";
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Logowanie błędu
|
||||||
|
Console.WriteLine($"Błąd: {ex.Message}");
|
||||||
|
// Zmiany nie zostały zatwierdzone (brak Commit lub Save)
|
||||||
|
// Sesja zostanie automatycznie zwolniona przez using
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wzorzec z wieloma operacjami
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void WieleOperacji(Login login, List<string> kody)
|
||||||
|
{
|
||||||
|
using (var session = login.CreateSession(false, false, "WieleOperacji"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var bledy = new List<string>();
|
||||||
|
|
||||||
|
foreach (var kod in kody)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var towar = tm.Towary.WgKodu[kod];
|
||||||
|
if (towar != null)
|
||||||
|
{
|
||||||
|
towar.Delete();
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
bledy.Add($"{kod}: {ex.Message}");
|
||||||
|
// Kontynuuj z następnym elementem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Save(); // Zapisz udane operacje
|
||||||
|
|
||||||
|
if (bledy.Any())
|
||||||
|
{
|
||||||
|
Console.WriteLine("Błędy: " + string.Join(", ", bledy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,366 @@
|
|||||||
|
# Session, Login, Database, BusApplication
|
||||||
|
|
||||||
|
Dokumentacja klas zarządzających połączeniem z bazą danych i sesjami w platformie enova365/Soneta.
|
||||||
|
|
||||||
|
## Hierarchia obiektów
|
||||||
|
|
||||||
|
```
|
||||||
|
BusApplication (Singleton)
|
||||||
|
└── Database[] (kolekcja baz danych)
|
||||||
|
└── Login (uwierzytelniony użytkownik)
|
||||||
|
└── Session[] (sesje robocze)
|
||||||
|
└── Module → Table → Row
|
||||||
|
```
|
||||||
|
|
||||||
|
## BusApplication
|
||||||
|
|
||||||
|
Singleton reprezentujący instancję aplikacji ERP. Tworzony podczas inicjalizacji systemu.
|
||||||
|
|
||||||
|
### Dostęp do instancji
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Singleton
|
||||||
|
BusApplication app = BusApplication.Instance;
|
||||||
|
|
||||||
|
// Dostęp do bazy danych po nazwie
|
||||||
|
Database db = BusApplication.Instance["BazaDemo"];
|
||||||
|
|
||||||
|
// Iteracja po wszystkich bazach
|
||||||
|
foreach (Database db in BusApplication.Instance)
|
||||||
|
{
|
||||||
|
Console.WriteLine(db.Name);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Właściwości
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `Instance` | `BusApplication` | Statyczny singleton |
|
||||||
|
| `Is365` | `bool` | `true` = wersja HTML, `false` = wersja okienkowa |
|
||||||
|
| `this[string]` | `Database` | Indeksator - baza po nazwie |
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
Abstrakcyjna klasa reprezentująca bazę danych. Konkretne implementacje dla wspieranych silników:
|
||||||
|
|
||||||
|
```
|
||||||
|
Database (abstrakcyjna)
|
||||||
|
└── SqlDatabase (abstrakcyjna)
|
||||||
|
├── MsSqlDatabase (SQL Server)
|
||||||
|
└── AzureDatabase (Azure SQL)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Uwaga:** MySqlDatabase oraz OracleDatabase nie są już obsługiwane.
|
||||||
|
|
||||||
|
### Konfiguracja
|
||||||
|
|
||||||
|
Obiekty Database są deserializowane z pliku `Lista baz danych.xml`.
|
||||||
|
|
||||||
|
### Właściwości
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `Name` | `string` | Nazwa bazy danych |
|
||||||
|
| `DefaultDatabase` | `bool` | Czy baza domyślna |
|
||||||
|
| `DatabaseName` | `string` | Nazwa bazy w silniku SQL (SqlDatabase) |
|
||||||
|
|
||||||
|
### Logowanie do bazy
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
Database db = BusApplication.Instance["BazaDemo"];
|
||||||
|
|
||||||
|
// ZALECANE: Logowanie z LoginParameters
|
||||||
|
Login login = db.Login(new LoginParameters
|
||||||
|
{
|
||||||
|
UserName = "Administrator",
|
||||||
|
UserPassword = "password"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Logowanie zintegrowane Windows
|
||||||
|
Login login = db.Login(new LoginParameters
|
||||||
|
{
|
||||||
|
UserName = LoginParameters.WindowsAuthenticationUser
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Login
|
||||||
|
|
||||||
|
Obiekt reprezentujący zalogowanego użytkownika. Zarządza sesjami.
|
||||||
|
|
||||||
|
### Tworzenie
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
Database db = BusApplication.Instance["BazaDemo"];
|
||||||
|
Login login = db.Login(new LoginParameters
|
||||||
|
{
|
||||||
|
UserName = "Administrator",
|
||||||
|
UserPassword = "password"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dostęp do informacji o operatorze
|
||||||
|
|
||||||
|
**WAŻNE:** Właściwości `Operator` i `Entitle` w klasie `Login` nie należy stosować, ponieważ używają obiektu z `ConfigSession` w sposób niekontrolowany.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// NIE ZALECANE:
|
||||||
|
// var op = login.Operator; // unikać!
|
||||||
|
// var ent = login.Entitle; // unikać!
|
||||||
|
|
||||||
|
// ZALECANE: Użyj w konkretnej sesji
|
||||||
|
using (var session = login.CreateSession(true, false, "Odczyt"))
|
||||||
|
{
|
||||||
|
var op = session.AuthorizationInfo.Operator;
|
||||||
|
Console.WriteLine($"Zalogowany: {op.Name} - {op.FullName}");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Właściwości informacyjne
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `IsWebUser` | `bool` | Czy operator pulpitu (web) |
|
||||||
|
| `Licencje` | `IEnumerable` | Pobrane licencje |
|
||||||
|
| `Database` | `Database` | Baza danych logowania |
|
||||||
|
|
||||||
|
### Tworzenie sesji
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ZALECANA sygnatura (czytelność + debugowanie)
|
||||||
|
Session session = login.CreateSession(
|
||||||
|
readOnly: false, // true = tylko odczyt
|
||||||
|
config: false, // true = dane konfiguracyjne
|
||||||
|
name: "MojaSesja" // nazwa sesji - pomocna przy debugowaniu
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Zawsze używaj wersji z parametrem `name`** - ułatwia debugowanie i identyfikację sesji.
|
||||||
|
|
||||||
|
### Dostęp do danych konfiguracyjnych
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ZALECANE: ExecuteConfig z lambdą (zwraca wartość prostą)
|
||||||
|
var opisDlaSzt = login.ExecuteConfig(configSession =>
|
||||||
|
configSession.GetTowary().Jednostki.WgKodu["szt"]?.Opis);
|
||||||
|
|
||||||
|
// NIE ZALECANE: login.ConfigSession
|
||||||
|
// var configSession = login.ConfigSession; // unikać!
|
||||||
|
```
|
||||||
|
|
||||||
|
**WAŻNE:** Używając `ExecuteConfig()` nie można zwracać obiektów sesyjnych z sesji konfiguracyjnej, ponieważ może być używana w innym wątku do innych celów. Zwracaj tylko wartości proste lub kopie danych.
|
||||||
|
|
||||||
|
### Sygnatury CreateSession
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public Session CreateSession(bool readOnly, bool config, string name)
|
||||||
|
public Session CreateSession(bool readOnly, bool config)
|
||||||
|
public Session CreateSession() // readOnly=false, config=false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Session
|
||||||
|
|
||||||
|
Fundamentalna klasa do zarządzania danymi. **Każda operacja na danych wymaga sesji.**
|
||||||
|
|
||||||
|
### Tworzenie
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ZAWSZE używaj using lub wywołuj Dispose()
|
||||||
|
using (var session = login.CreateSession(false, false, "MojaSesja"))
|
||||||
|
{
|
||||||
|
// operacje na danych
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typy sesji - macierz
|
||||||
|
|
||||||
|
| ReadOnly | Config | Zastosowanie |
|
||||||
|
|----------|--------|--------------|
|
||||||
|
| `false` | `false` | **Edycja operacyjna** - dokumenty, kartoteki |
|
||||||
|
| `true` | `false` | **Odczyt operacyjny** - raporty, wyświetlanie |
|
||||||
|
| `false` | `true` | **Edycja konfiguracyjna** - ustawienia systemu |
|
||||||
|
| `true` | `true` | **Odczyt konfiguracyjny** - odczyt słowników |
|
||||||
|
|
||||||
|
**WAŻNE:** W sesji operacyjnej (`config: false`) nie można modyfikować obiektów konfiguracyjnych. Do modyfikacji konfiguracji wymagana jest sesja konfiguracyjna (`config: true`).
|
||||||
|
|
||||||
|
### Właściwości
|
||||||
|
|
||||||
|
| Właściwość | Typ | Opis |
|
||||||
|
|------------|-----|------|
|
||||||
|
| `ReadOnly` | `bool` | Czy sesja tylko do odczytu |
|
||||||
|
| `IsConfig` | `bool` | Czy sesja konfiguracyjna |
|
||||||
|
| `Name` | `string` | Nazwa sesji |
|
||||||
|
| `Login` | `Login` | Obiekt logowania |
|
||||||
|
| `Database` | `Database` | Baza danych |
|
||||||
|
|
||||||
|
### Metody zarządzania danymi
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Zapisanie zmian do bazy
|
||||||
|
session.Save();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dane operacyjne vs konfiguracyjne
|
||||||
|
|
||||||
|
**Dane operacyjne (`config=false`):**
|
||||||
|
- Dokumenty, kartoteki, transakcje
|
||||||
|
- Zawsze odczytywane z bazy (aktualność)
|
||||||
|
- Modyfikacje zapisywane natychmiast przy `Save()`
|
||||||
|
|
||||||
|
**Dane konfiguracyjne (`config=true`):**
|
||||||
|
- Słowniki, definicje, ustawienia
|
||||||
|
- Buforowane w cache (optymalizacja)
|
||||||
|
- Modyfikowane rzadko, odczytywane często
|
||||||
|
- Określane atrybutem `config="true"` w business.xml
|
||||||
|
|
||||||
|
### Wiele sesji jednocześnie
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Normalne zjawisko - wiele sesji może współistnieć
|
||||||
|
using (var session1 = login.CreateSession(true, false, "Lista1"))
|
||||||
|
using (var session2 = login.CreateSession(true, false, "Lista2"))
|
||||||
|
{
|
||||||
|
// Obie sesje mogą odczytywać te same dane
|
||||||
|
var tm1 = session1.GetTowary();
|
||||||
|
var tm2 = session2.GetTowary();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transakcje biznesowe - Session.Logout()
|
||||||
|
|
||||||
|
**WAŻNE:** Każda zmiana obiektu biznesowego MUSI być w transakcji!
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var session = login.CreateSession(false, false, "Edycja"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var towar = tm.Towary.WgKodu["KOD001"];
|
||||||
|
|
||||||
|
// Logout(editMode: true) - transakcja EDYCYJNA (można modyfikować)
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
towar.Nazwa = "Nowa nazwa";
|
||||||
|
var cena = towar.Ceny["Hurtowa"];
|
||||||
|
cena.Netto = new DoubleCy(100.00m);
|
||||||
|
transaction.Commit(); // Zatwierdza zmiany w sesji
|
||||||
|
}
|
||||||
|
// Brak Commit() = rollback (przywrócenie stanu sprzed Logout)
|
||||||
|
|
||||||
|
session.Save(); // Zapisuje do bazy danych
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logout(editMode: false) - transakcja tylko do odczytu
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using (var session = login.CreateSession(false, false, "Przeglad"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
var towar = tm.Towary.WgKodu["KOD001"];
|
||||||
|
|
||||||
|
// Transakcja tylko do odczytu
|
||||||
|
using (var readTrans = session.Logout(editMode: false))
|
||||||
|
{
|
||||||
|
// Tutaj NIE można modyfikować
|
||||||
|
|
||||||
|
// Ale można otworzyć zagnieżdżoną transakcję edycyjną
|
||||||
|
using (var editTrans = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var cena = towar.Ceny["Hurtowa"];
|
||||||
|
cena.Netto = new DoubleCy(200m);
|
||||||
|
editTrans.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// WAŻNE: Commit wymagany też dla transakcji readonly!
|
||||||
|
// Inaczej zmiany z zagnieżdżonych transakcji edycyjnych przepadną
|
||||||
|
readTrans.Commit();
|
||||||
|
}
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Metoda | Opis |
|
||||||
|
|--------|------|
|
||||||
|
| `session.Logout(editMode: true)` | Transakcja edycyjna - można modyfikować |
|
||||||
|
| `session.Logout(editMode: false)` | Transakcja tylko do odczytu |
|
||||||
|
| `transaction.Commit()` | Zatwierdza zmiany (wymagane dla obu typów!) |
|
||||||
|
| `transaction.CommitUI()` | Zatwierdza + odświeża UI |
|
||||||
|
| `transaction.Dispose()` | Bez Commit = rollback (także zagnieżdżonych zmian) |
|
||||||
|
|
||||||
|
## Kompletny przykład
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// 1. Pobranie instancji aplikacji
|
||||||
|
BusApplication app = BusApplication.Instance;
|
||||||
|
|
||||||
|
// 2. Pobranie bazy danych
|
||||||
|
Database db = app["MojaBaza"];
|
||||||
|
|
||||||
|
// 3. Logowanie
|
||||||
|
Login login = db.Login(new LoginParameters
|
||||||
|
{
|
||||||
|
UserName = "admin",
|
||||||
|
UserPassword = "haslo"
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Utworzenie sesji (zawsze z nazwą!)
|
||||||
|
using (var session = login.CreateSession(false, false, "Import"))
|
||||||
|
{
|
||||||
|
// 5. Pobranie modułu (extension method)
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
|
||||||
|
// 6. Transakcja biznesowa - WYMAGANA dla zmian!
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
var nowyTowar = new Towar();
|
||||||
|
tm.Towary.AddRow(nowyTowar);
|
||||||
|
nowyTowar.Kod = "IMPORT001";
|
||||||
|
nowyTowar.Nazwa = "Zaimportowany towar";
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Zapis do bazy
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
// 8. Session automatycznie Dispose() przez using
|
||||||
|
```
|
||||||
|
|
||||||
|
## Thread-safety
|
||||||
|
|
||||||
|
### Obiekty multi-threaded (można współdzielić między wątkami)
|
||||||
|
- `BusApplication`
|
||||||
|
- `Database`
|
||||||
|
- `Login`
|
||||||
|
|
||||||
|
### Obiekty single-threaded (NIE współdzielić)
|
||||||
|
- `Session`, `Module`, `Table`, `Row`, `Context`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// DOBRZE - Login można współdzielić, każdy wątek tworzy własną sesję
|
||||||
|
Login sharedLogin = db.Login(new LoginParameters { UserName = "admin", UserPassword = "haslo" });
|
||||||
|
|
||||||
|
Parallel.ForEach(items, item => {
|
||||||
|
using (var session = sharedLogin.CreateSession(false, false, "Watek"))
|
||||||
|
{
|
||||||
|
var tm = session.GetTowary();
|
||||||
|
using (var transaction = session.Logout(editMode: true))
|
||||||
|
{
|
||||||
|
// operacje...
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
session.Save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sesja bez interfejsu graficznego
|
||||||
|
|
||||||
|
Sesja działa w warstwie logiki biznesowej - **nie wymaga UI**.
|
||||||
|
|
||||||
|
Przykłady użycia bez interfejsu:
|
||||||
|
- **Harmonogram Zadań** - usługa Windows wykonująca operacje bazodanowe
|
||||||
|
- **Importy danych** - procesy wsadowe
|
||||||
|
- **Testy jednostkowe** - automatyczne testy logiki
|
||||||
|
- **API REST** - obsługa żądań HTTP
|
||||||
Reference in New Issue
Block a user