České vysoké učení technické v Praze Fakulta elektrotechnická
Bakalářská práce
Klient pro komunikaci se systémem ABRA-Gx Radek Mazár
Vedoucí práce: Ing. Michal Valenta, PhD. Studijní program: Elektrotechnika a výpočetní technika, strukturovaný, bakalářský Obor: Výpočetní technika červen 2007
Obsah 1 ÚVOD................................................................................................................................................2 1.1 Zadání projektu..........................................................................................................................2 1.1.1 Úvod do problematiky.......................................................................................................2 1.1.2 Cíl projektu........................................................................................................................2 1.1.3 Základní popis....................................................................................................................2 1.1.4 Závazné cíle projektu.........................................................................................................3 1.1.4.1 Cíle.............................................................................................................................3 1.1.4.2 Tvorba skladových a daňových dokladů....................................................................3 1.1.4.3 Synchronizace číselníkových agend...........................................................................3 1.1.4.4 Datové přenosy...........................................................................................................3 1.2 Model použití.............................................................................................................................4 1.2.1 Centrála..............................................................................................................................4 1.2.2 Pobočky (hnízda)...............................................................................................................4 2 POPIS PROBLÉMU, SPECIFIKACE CÍLE....................................................................................5 2.1 Náčrt řešení................................................................................................................................5 2.2 Možnosti implementace.............................................................................................................6 2.2.1 On-line řešení.....................................................................................................................6 2.2.2 Off-line řešení....................................................................................................................6 2.3 Volba implementace...................................................................................................................6 2.4 Výběr vývojového prostředí, DB stroje.....................................................................................7 2.5 Další možnost implementace.....................................................................................................7 3 ANALÝZA A NÁVRH ŘEŠENÍ.......................................................................................................9 3.1 Analýza obou aplikací................................................................................................................9 3.1.1 Server.................................................................................................................................9 3.1.1.1 Export.......................................................................................................................11 3.1.1.2 Import.......................................................................................................................11 3.1.2 Klient................................................................................................................................11 3.1.2.1 Klientská databáze....................................................................................................11 3.1.2.2 ER-model..................................................................................................................12 3.1.2.3 Klientská aplikace....................................................................................................14 3.2 Usecase diagram......................................................................................................................14 4 REALIZACE...................................................................................................................................15 4.1 Serverová aplikace...................................................................................................................15 4.1.1 Nastavení Abry.................................................................................................................15 4.1.2 Nastavení aplikace...........................................................................................................16 4.1.3 Importy dat.......................................................................................................................16 4.1.4 Exporty dat.......................................................................................................................16 4.2 Klientská aplikace....................................................................................................................16 4.2.1 GUI...................................................................................................................................17 4.2.2 Hlavní okno (základní menu)...........................................................................................18 4.2.3 Okno hlavičky dokumentu (TFormDocumentHeader)....................................................18 4.2.4 Třídy pro zobrazení hlaviček...........................................................................................19 4.2.5 Okno pro zadání řádků.....................................................................................................19 4.2.6 Framy pro řádkové údaje.................................................................................................20 4.2.6.1 Obecná třída pro řádek dokladu (TFrameDocumentRow).......................................20 4.2.6.2 Třídy pro zobrazení řádků........................................................................................20 4.2.7 Framy pro zadávání údajů dokumentů.............................................................................20 4.2.7.1 Číselná hodnota........................................................................................................20 4.2.7.2 Textová hodnota (TFrameDescription a TFrameDescriptionRow)..........................21
4.2.7.3 Datum (TFrameDateTimePicker).............................................................................21 4.2.7.4 Číselníková položka.................................................................................................21 4.2.8 Třídy pro zobrazení číselníků (TFormRoll) ....................................................................21 4.2.9 Vizuální třídy pro Export/Import.....................................................................................22 4.2.10 Třídy pro uchování dat...................................................................................................23 4.2.10.1 Atribut (TAttribute) ...............................................................................................23 4.2.10.2 Seznamy (TAttributeList a TDocumentList) .........................................................24 4.2.10.3 Bázová třída dokumentu (TDocument) .................................................................24 4.2.10.4 Bázová třída hlaviček (TDocumentHeader) ..........................................................25 4.2.10.5 Bázová třída řádků (TDocumentRow) ..................................................................25 4.2.10.6 Vlastní třídy hlavičkových dokumentů..................................................................25 4.2.10.7 Vlastní třídy řádkových dokumentů.......................................................................25 5 TESTOVÁNÍ...................................................................................................................................26 5.1 Jednotkové testy.......................................................................................................................26 5.2 Testy integrace modulů (Integrační testy)................................................................................26 5.3 Validační testy..........................................................................................................................26 5.4 Systémové testy.......................................................................................................................26 5.5 Výsledky testování (Shrnutí)...................................................................................................27 6 ZÁVĚR............................................................................................................................................28 7 SEZNAM POUŽITÉ LITERATURY..............................................................................................29 8 Přílohy.............................................................................................................................................30 8.1 Obsah přiloženého CD.............................................................................................................30
Prohlášení: Prohlašuji, že jsem svou bakalářskou práci vypracoval samostatně a použil jsem pouze podklady uvedené v přiloženém seznamu. Nemám závažný důvod proti užití tohoto školního díla ve smyslu §60 zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon). V Táboře dne 31.5.2007 …..................................................................... -1-
1 ÚVOD 1.1 Zadání projektu 1.1.1 Úvod do problematiky ABRA Gx je jedním z produktů ERP (Enterprise Resource Planning). Jde o informační systém Client/Server pro střední a větší firmy s možností provozu na serverové platformě MS Windows nebo OS Linux. S ohledem na použitou technologii vyžaduje relativně výkonný HW. Ne všichni potenciální uživatelé tento HW mají a zavedení systému je pak limitováno nejen investicí do SW. Mimo to není v mnohých případech vyžadována úplná funkčnost. Systém ABRA Gx je dodáván jako otevřený systém, k dispozici je celý objektový model systému přístupný přes otevřené OLE rozhraní. Pomocí otevřeného rozhraní lze data ze systému ABRA Gx číst a dále zpracovávat.
1.1.2 Cíl projektu Cílem projektu je vytvořit SW (pracovní název GxExt) zajišťující základní funkce nutné pro nákup a prodej zboží, tzn. : • • •
Tvorbu skladových dokladů a daňových dokladů Synchronizaci nutných číselníkových agend Datové přenosy z a do ABRA Gx Zadání vychází z předpokladu, že na centrále firmy existuje síťová instalace ABRA Gx. Zde je centrální evidence, včetně tvorby a správy číselníkových agend (organizační struktura, adresář obchodních partnerů, číselník skladových karet včetně prodejních cen, evidence DPH atd). Na vzdálených pobočkách firmy je instalován GxExt, data z centrály jsou distribuována na pobočky. Pobočka pouze vytváří stanovené doklady a dávkově je exportuje do centrály. Každá pobočka je unikátní kódem střediska a kódem skladu.
1.1.3 Základní popis Systém ABRA Gx pracuje s daty uloženými v databázovém serveru Firebird. S daty lze pracovat dvěma způsoby, pomocí OLE rozhraní, nebo přímou komunikací s SQL serverem. S ohledem na možnosti a potřeby předpokládám práci s daty řešit takto : • • • •
Načítání dat z ABRA Gx (číselníky atd) řešit přímou komunikací s SQL, aby byla zajištěna větší rychlost práce s daty. Zápis externích dat do ABRA Gx (doklady) řešit přes OLE. Tím bude zajištěna konzistence vkládaných dat a vzhledem k dávkovému režimu, není rychlost rozhodujícím kriteriem. Předávání dat mezi mezi SW a systémem ABRA Gx řešit formou textových souborů s oddělovačem, nebo použít XML formát Program zpracovat v prostředí Delphi 6, jako Win aplikaci
-2-
1.1.4 Závazné cíle projektu 1.1.4.1 Cíle
Výsledkem budou dva programy: 1. Program na centrále vytváří exportní soubory pro pobočku provádí import dat z pobočky 2. Program na pobočce importuje data z centrály vytváří, ukládá a tiskne stanovené doklady exportuje data na centrálu 1.1.4.2 Tvorba skladových a daňových dokladů
1. Skladové doklady Příjemka Výdejka (dodací list) Převodka (převod mezi sklady) 2. Daňové doklady Prodej za hotové (Pokladní příjem) Prodej na fakturu (Faktura vydaná) Východiskem pro uživatelské rozhraní je ABRA Gx. Vzhledem k použití je možno některé údaje stanovovat v konfiguraci (středisko, sklad, druh pohybu atd.). 1.1.4.3 Synchronizace číselníkových agend
Základním prvkem bude seznam – číselník, který bude využíván pro výběr údajů do dokladů. Editace není možná, oprava dat je možná pouze importem z centrály. Jde o tyto číselníky: seznam zboží (skladové karty) adresář zakázky a obchodní případy Synchronizace bude jednostranná, tzn. pouze z centrály na pobočku. Data na pobočce budou vždy kompletně přepsána daty z centrály. Mimo to přenášet z centrály na pobočky údaje o: aktuálním účetním období další údaje nutné pro tvorbu korektních dokladů kód střediska a kód skladu (tento údaj bude různý pro jednotlivé pobočky) 1.1.4.4 Datové přenosy
Exporty centrála – data načítat přímo z SQL Firebird a ukládat do textových, nebo XML souborů. -3-
Importy centrála – data (doklady) načítat z textových, nebo XML souborů a s využitím OLE ukládat do ABRA Gx. Exporty pobočka – exportovat data za zvolené období a ukládat je do stanoveného formátu (k tomu vést evidenci již provedených exportů s možností opakování). Importy pobočka – načtení dat z centrály.
1.2 Model použití 1.2.1 Centrála Toto řešení přichází do úvahy především v případě off-line řešení. Na centrále (tam kde je instalace systému Abra Gx) bude pracovník pověřený prováděním importů, ten obdrží např. mailem (přes ftp server nebo podobně) exportní soubor(y), ty uloží na svůj disk. Spustí importovací program, zvolí příslušný soubor a naimportuje jej do systému Abra. Z toho plyne, že tento pracovník musí mít na svém počítači buď samotnou instalaci Abry, nebo mít (v případě síťové instalace) přístup k síťové verzi Abry a mít registrované otevřené rozhraní Abry (to se dá udělat uživatelsky jednoduše přes GUI účetního systému). Dále je potřeba aby byl v Abře uživatel, který má práva používat OLE rozhraní a práva potřebná k uložení dokladů (řady dokladů, sklady atd...). V případě on-line řešení by celá serverová část pracovala automaticky bez potřeby uživatelského zásahu pro provedení importu.
1.2.2 Pobočky (hnízda) Na pobočkách (místa kde je pouze klientská část a nemá přímé spojení na Abru) je pracovník pověřený evidencí dokladů. Zde jsou dva scénáře použití. V prvním případě půjde o interakci se zákazníkem. To znamená, přijde zákazník a má zájem o nějaké zboží, které může být buď zaplaceno v hotovosti (pokladní příjem) nebo vydáno na fakturu (faktura vydaná). Tedy zákazník řekne co chce, pověřený pracovník vystaví příslušný doklad, ten uloží, vytiskne pro zákazníka, tomu pak předá doklady, vydá zboží. V druhém případě se jedná o vnitřní záležitost, tedy například převodka mezi sklady, tzn. zboží putuje pouze mezi sklady v rámci firmy. Přijede někdo z jiného skladu s požadavkem na převod zboží, zaměstnanec vystaví převodku výdej, vydá zboží. Tím je převod evidován. U tohoto typu dokladu není třeba tisk. Dále jde o příjemku na sklad, kdy naskladňujeme zboží od dodavatele. Scénář je podobný jako u převodky, tedy pouze se vytvoří doklad příjemka, čímž se příjem zaeviduje, dále provede další úkony potřebné k příjmu zboží vůči například dodavateli atp. Opět není třeba tisknout.
-4-
2 POPIS PROBLÉMU, SPECIFIKACE CÍLE Tento systém je primárně určen pro firmu Paliva Písek a.s. zabývající se prodejem především tuhých paliv, jako je uhlí, koks atp. Pro její účely a potřeby bude tedy program psán. Celý projekt by ale měl být postaven tak, aby se dal bez větších úprav implementovat i v jiné firmě s podobnými zaměřením a potřebami, což u firem se skladovým hospodářstvím by mělo být ve většině případů. Bude potřeba tedy data (doklady) evidovat a nějakým způsobem uchovávat v počítači na první pohled alespoň po dobu, než budou naimportována na centrále do Abry, v případě, že bude ale například zboží vráceno, je potřeba mít možnost si nějakým způsobem ověřit, že bylo zboží opravdu vydáno. Tzn. že to bude ověřeno na centrále nebo ve vlastním systému systému. Z toho plyne, že bude vhodné mít u dokladů příznak exportu a v programu evidovat doklady i starší než je datum posledního exportu. Z celé koncepce systému plyne, že bude vhodné pro ukládání dat použít databázový server, tedy celou aplikaci klienta stavět jako dvouvrstvou, kde se data uloží do databáze a pracovat se s nimi bude pomocí k tomu vytvořené aplikace. Co se týká přímo práce s daty, vzhledem k tomu, že se plánuje na každé pobočce pouze jeden počítač, který bude sloužit k evidenci dokladů, bude vhodné použití nějaké embeded verze databázového serveru. Nebude tady potřeba nějak řešit nebo ošetřovat přístupová práva k tabulkám atp. v databázi. Vhodné řešení tedy bude takové, že se všemi doklady se bude pracovat jako s objekty v paměti a s databází se bude pracovat pouze při ukládání a načítáni dokladu.
2.1 Náčrt řešení Z definovaných požadavků lze vytvořit přibližné schéma objektů a jejich závislostí. Nejsou zde přesněji specifikovány atributy a metody jednotlivých objektů.
-5-
Je jasné, že bude třeba vazeb na číselníkové tabulky. To budou vlastně atributy, ve kterých bude uložen odkaz na řádek tabulky.
2.2 Možnosti implementace Ze samotné specifikace problému plynou dvě základní možnosti jeho řešení. Jedná se o řešení, kde máme trvalé spojení s centrálou (on-line), a řešení, kde je možnost posílat jednou za čas data (off-line).
2.2.1 On-line řešení V tomto případě je možné „serverovou“ část aplikace zcela automatizovat, to znamená, že by nebylo třeba zaměstnance, který by se staral o import dokladů na centrále. Všechno by se dělo automaticky na požadavek od hnízda. Z toho plyne, že by se uživatel vůbec nemusel starat o žádné exporty a importy. Dále by zde bylo vhodné nějakým způsobem zabezpečit jak komunikaci mezi klientem a serverem, tak to aby nedošlo k připojení nežádoucích osob (resp. počítačů). Jako nejvhodnější se pro tento styl řešení jeví použít rámce .NET a jeho Remotingu. Zde by se pro komunikaci vytvořila třída, která obsahuje funkce pro vytvoření, uložení a načtení dokladů a za pomoci vzdáleného volání vytváří doklady přímo v Abře. Toto řešení by bylo velmi efektivní zejména proto, že by se navíc nemuselo řešit ukládání dokladů na pobočkách, ale všechna data by byla uložena přímo v Abře. Serverová část by s Abrou komunikovala přes OLE zejména kvůli ukládání dokladů a možnosti validace dokladů. Co se týká bezpečnosti nabízí platforma .NET nepřeberné množství možností jak zabezpečit přenos včetně komprimací atd. Jednoduše lze stream, před tím než je vypuštěn do sítě, „prohnat“ šifrováním a komprimací a na druhé straně naopak dekomprimovat a dešifrovat. Další on-line možnost je taková, že by hnízda fungovala s časově omezeným spojením a centrála s trvalým. I v tomto řešení by šlo serverovou část (centrálu) zcela automatizovat. Komunikace by se omezila pouze na dobu, kdy probíhá export dat na pobočku a import dat z pobočky. Během této komunikace by se naimportovaly doklady vzniklé na pobočce a aktualizovala data číselníkových tabulek klientské části (hnízda). Celá komunikace by se opět dala vytvořit za použití .NET Remoting.
2.2.2 Off-line řešení Toto řešení je nejvíce náročné na potřebu zásahu uživatele, neboť musí být obsloužena jak klientská část (hnízdo), tak i serverová část (centrála), kde je potřeba nějakým způsobem data přijmout a potom je naimportovat do účetního systému Abra Gx. Z těchto potřeb je patrné, že bude vhodné vytvořit dva programy, jeden pro pobočku a jeden pro centrálu. Dále bude nutné definovat komunikační formát, ve kterém si budou programy vyměňovat informace.
2.3 Volba implementace Na výběr implementace měly základní vliv potřeby firmy Paliva Písek a.s. a vzhledem k tomu, že tato firma nedisponuje zejména na pobočkách pevným připojením k internetu a veřejnou IP na serveru centrály, jedinou možností bylo off-line řešení. Dále mělo velkou váhu to, že toto řešení je tady již do jisté míry implementováno a zaměstnancům firmy je tento způsob blízký, mají ho zažitý a nebude tedy vetší problém při přechodu na nový program, který je postupem času možno rozšířit o nové funkce, neboť je počítáno s tím, že se s příchodem nových možností postupně přejde na modernější způsob komunikace mezi centrálou a hnízdy.
-6-
2.4 Výběr vývojového prostředí, DB stroje Nyní je již jasné, že se budou programovat dvě aplikace, pro centrálu a pro hnízda, a že bude potřeba nějakého úložiště dat, tedy databázového stroje pro klienta. Výběr byl celkem jednoznačný: je potřeba databáze, která bude v nejlepším případě volně dostupná i pro komerční účely a bude se s ní dobře pracovat ze zvoleného vývojového prostředí. Jako nejlepší se nakonec jevila kombinace FireBirdu a nějakého vývojového prostředí od firmy Borland, protože FireBird navázal na volně šiřitelnou verzi InterBase od Borlandu a je s ní plně kompatibilní ve verzi 1.5 a snadno se s touto databází komunikuje s komponentami z některého prostředí od zmíněné firmy (Delphi, C++ Builder atp..). Co se týká konkrétního prostředí, jako nejvhodnější se jeví použití některého jazyka nad rámcem .NET kvůli snazší realizaci dříve zmíněných budoucích úprav a změn (Remoting atd..). Jako nejvhodnější se nakonec jevilo použití Delphi .NET proto, že dřívější verze serverové části byla psána v Borland Delphi 6 a její kód by se tedy dal přímo upravit pro novou verzi programu.
2.5 Další možnost implementace Jako další zajímavé řešení klientské části by se dalo použít nástrojů Borland ECO (Enterprise Core Objects). Pomocí tohoto nástroje lze vizuálně definovat UML schéma projektu. V našem případě by to znamenalo vymodelovat databázi, tím se vytvoří objekty zastupující jednotlivé dokumenty. Přímo pomocí tohoto nástroje je pak možno, po nadefinování spojení na databázi, aby se celá databáze včetně závislostí apod. vytvořila sama podle našeho schématu. Další zajímavá možnost je také uložení všech dat do XML souboru. V tomto případě by se celá klientská aplikace obešla bez jakéhokoliv databázového serveru. Velikost souboru XML by byla v řádech jednotek až desítek megabytů. Nespornou výhodou tohoto řešení by asi byla rychlost vývoje, zamezení chyb v kódu a podobně. Nevýhodou by pak bylo to, že by bylo nutné přepsat celou serverovou část, definovat jiný způsob komunikace (zde by byl asi mnohem vhodnější XML formát) atd.. U tohoto řešení by byly všechny tabulky vytvořeny jako objekty a bylo by tedy vhodné maximálně využít společných vlastností a dědičnosti a při správném návrhu by nebylo třeba definovat žádný atribut ani vazbu na číselník dvakrát.
-7-
Orientační schéma by pak vypadalo asi nějak takto:
Toto schéma zároveň přesně popisuje problém, který má za úkol řešit naše aplikace. Znázorňuje, co bude třeba uchovávat. Pro přehlednost nejsou uvedeny vztahy hlaviček na řádky, ty jsou ale zřejmé a znázorněny jsou v obecném schématu výše. Jde o vazbu, kde každá hlavička se odkazuje na 1 až N řádků svého typu.
-8-
3 ANALÝZA A NÁVRH ŘEŠENÍ 3.1 Analýza obou aplikací Podle zadání projektu a specifikace cílů je jasné, že celý projekt musí být napsán takovým způsobem, aby ho bylo možno v první řadě plně využívat a v druhé řadě v něm musí být počítáno i s tím, že se bude v budoucí době rozšiřovat o nové funkce a možnosti.
3.1.1 Server Co je to otevřené rozhraní (OLE) Abry? Zjednodušeně OLE rozhraní slouží ke komunikaci programů mezi sebou. Je implementováno v sytému Win 95 a vyšších. OLE v ABRA G3:
Abra má otevřené rozhraní ve dvou formách, jednak jako spustitelný soubor (OLE Automation Server) a jednak jako dynamicky linkovanou knihovnu dll. V našem případě s přihlédnutím k vyšší rychlosti použijeme knihovní verzi AbraOLELib.
-9-
Bez alespoň částečné znalosti otevřeného rozhraní Abry by byla analýza problému této části nemožná, proto je v následujících dvou podkapitolách je zmíněno použití několika tříd otevřeného rozhraní Abry a jejich metod. Jsou to tyto: ApplicationClass: Třída Application je stavebním kamenem otevřeného rozhraní. Třída poskytuje služby na úrovni aplikace, umožňuje především přihlášení / odhlášení, výběr spojení, výběr firmy, správu transakcí, přístup k business objektům v systému (např. firma, faktura, objednávka atd.) a přístup k DynSQL (což je nástroj pro dotazování do databáze s různými omezeními a řazením). procedure SQLExecute(const ASQL: WideString); Popis: Funkce vykoná jakýkoliv SQL příkaz (tedy i INSERT, UPDATE, DELETE a DDL) v kontextu běžící transakce. Uživatel musí mít právo použít funkci SQLUpdate. procedure SQLSelect(const ASQL: WideString; AResult: _Strings); Popis: Funkce vykoná jakýkoliv SQL příkaz typu SELECT v kontextu běžící transakce. Výsledek je vrácen v AResult ve formátu CSV (každá položka AResult odpovídá jednomu záznamu, jednotlivé sloupečky jsou odděleny středníkem). Uživatel musí mít právo použít funkci SQLSelect. function CreateObject(const CLSID: WideString): IDispatch; Popis: Funkce vrátí novou instanci objektu DataObject. Parametr CLSID je pakovaný GUID nebo je možné s použitím "@" uvést "rozumný" název třídy (např. CreateValues("@Firm")). Pokud třída není v systému nalezena, je vyvolána výjimka. Vrácen je interface IDispatch, na kterém si můžeme zavolat jakékoliv metody (objekt je samozřejmě musí implementovat). Vrácený objekt také podporuje generický interface DataObject. function
CreateValues(const CLSID: WideString): ObjectData;
Popis: Funkce vrátí novou instanci objektu ObjectData. Parametr CLSID je pakovaný GUID nebo je možné s použitím „@“ uvést „rozumný“ název třídy. Pokud třída není v systému nalezena, je vyvolána výjimka. _Strings (NxStrings): Třída podobná Delphi třídě TStrings. V této podobě dovoluje držet seznam (kolekci) řetězců a umožňuje základní operace nad nimi. procedure SaveToFile(const FileName: WideString); Popis: Uloží všechny řetězce do souboru FileName. DataObject: Objekty této třídy jsou určeny k manipulaci s daty v systému (jinými slovy výkonné objekty určené k manipulaci s business objekty dané třídy). Tedy každá instance objektu třídy DataObject umí manipulovat s business objekty své třídy. Vytvořený DataObject je vždy vytvořený pro objekty určitých business objektů (např. pro skladové karty musíme mít jednu instanci, pro faktury jinou instanci atd.). Třída poskytuje základní prostředky pro vytváření nových objektů, jejich opravu a jejich mazání. Objekty DataObject se vytvářejí voláním metody Application.CreateObject(). function CreateNewFromValues(const Values: ObjectData): WideString; Popis: Metoda uloží nový objekt této třídy. Nejdříve je nutné naplnit všechny potřebné hodnoty do objektu třídy ObjectData (stejné třídy) a předat jej této funkci. Systém se pak pokusí objekt uložit. Pokud během ukládání nastane problém (chybná data, validace, atd.), je vyvolána výjimka. Pokud byl objekt úspěšně uložen, metoda vrátí OID uloženého objektu. function ValidateValues(const ObjectData): WideString;
OBJID:
WideString;
const
Values:
Popis: Metoda provede validaci dat. Parametrem OBJID říkáme, který objekt chceme opravit a parametr Values zase říká, jaká data chceme ověřit. Každý business objekt definuje, co se má před jeho uložením zkontrolovat. Výsledkem kontrol je typicky zpráva, proč není možné právě tento business objekt uložit. Pokud je vrácený řetězec prázdný, znamená to, že data jsou ověřena a správná. Kladné ověření dat nezaručuje, že se podaří tento objekt uložit. Každý objekt těsně před uložením je vhodné takto ověřit (platí i pro nové objekty). procedure PrefillValues(const Values: ObjectData);
- 10 -
Popis: Metoda se používá při zakládání nových business objektů. Metoda neudělá nic jiného, než že předvyplní všechny údaje, které je možné předvyplnit. Typicky objekt vytvoříme, předvyplníme jeho hodnoty, vyplníme některá položky objektu (které zadal uživatel nebo my), objekt ovalidujeme a uložíme. ObjectData: Třída ObjectData drží data. Rozhraní třídy definuje univerzální přístup ke všem vlastnostem business objektů. Instance jsou vytvářeny voláním Application.CreateValues() nebo DataObject.GetValues(). Instance se vždy vytvářejí pro určitý business objekt. Jeden objekt pak drží data jednoho business objektu. property ValueByName[const Name: WideString]: OleVariant; Popis: Pokud známe název hodnoty, můžeme k ní přistupovat přímo přes její jméno Name. Pokud zadáme název Name, který není v business objektu definován, je vyvolána výjimka, jinak je vrácena hodnota. Přístup je Read / Write.
Ostatní třídy a jejich metody (včetně zmíněných) jsou uvedeny v příloze (soubor g3doc.chm). 3.1.1.1 Export
Zde je požadavek celkem jasný. Jak částečně plyne i ze zadání, tato část se musí starat o import souborů a export číselníků. Vzhledem k tomu, že číselníky jsou v Abře jednotlivé tabulky, z kterých navíc nebude třeba exportovat všechny sloupce, nejvhodnější (kvůli rychlosti) bude použití prostého SQL dotazu nad jednou tabulkou a uložení do souboru. K tomu bude vhodné použít přímo instance OLE třídy NxStrings a SQL dotazu přes OLE rozhraní nad připojenou databází pomocí metody SqlSelect instance třídy ApplicationClass (ta je základním spojením na aplikační sever systému Abra a zprostředkovává veškeré spojení na něj a na DB), která má za parametry SQL dotaz jako string a odkaz právě na instanci třídy NxStrings. Ta je obdobou třídy TStrings (nebo TStringList) z Delphi. Do její instance je po volání ApplicationClass.SqlSelect uložen výsledek v obdobě formátu CSV (Comma-Separated Values, neboli hodnoty oddělené čárkami), kde jsou hodnoty odděleny středníky. Tento výsledek lze pak metodou NxStrings.SaveToFile, která má za parametr cestu k souboru jako String, snadno uložit do výstupního souboru. 3.1.1.2 Import Import bude taktéž probíhat celý pomocí otevřeného rozhraní. Z hlediska rychlosti by bylo výhodnější použít metodu SQLExecute třídy ApplicationClass, ale nebyla by zde zaručena konzistence dat jinak, než jen na úrovní databáze (nebo by musela být doplněna do programu), a to je nežádoucí. Vhodnější tedy bude použít pro vkládání dat Business objekty jednotlivých typů dokladů (Příjemka, Faktura vydaná...). Ty jsou v otevřeném rozhraní reprezentovány potomky třídy DataObject, kteří ji rozšiřují o některé metody. V tomto případě ale bez problémů vystačíme s použitím metod nadřízené třídy DataObject. Objekty budou předvyplněny metodou PrefillValues tříd jednotlivých dokumentů a doplněny importními údaji. Poté proběhne samotná validace, která nám zaručí konzistenci dat a vrátí případné chyby. Pak budou data uložena do databáze. 3.1.2 Klient 3.1.2.1 Klientská databáze
Jedná se o databázi, kde budou uložena data na klientské stanici. Jedná se o samotné doklady Příjemek, Faktur vydaných, Pokladních příjmů a Převodek. Dále zde budeme uchovávat číselníkové tabulky, ve kterých budou uloženy např. řady dokladů, DPH sazby atd. Dále je možno uložit do tabulky i informace potřebné pro běh programu nebo implicitní hodnoty pro předvyplnění dokladů apod. - 11 -
Z těchto požadavků vyplývá, že nepůjde o složitou databázi ani o nikterak náročnou na konzistence dat. Zaručeny musí být především vazby dokladů na číselníky a to aby byly vyplněny povinné údaje. Protože databáze Abry je otevřená, bude vhodné pro vytvoření klientské databáze použít například domény z databáze Abry. Tím bude zaručena typová shodu mezi daty z klienta a centrály. 3.1.2.2 ER-model
Tento model vychází z dříve zmíněného schématu (implementace pomocí Borland ECO). V našem případě, ho bude ale potřeba upravit. Protože budeme vycházet z domén Abry, takže například kód firmy má jinou doménu než kód období atd. Další problém je v tom, že v tomto řešení by pro ID všech číselníků byla použita entita Roll, z čehož plyne, že by zde mohlo dojít k duplicitám a to by mohl být problém např. při kaskádovitém mazání záznamů z číselníků (nejednoznačnost + došlo by k vymazání nežádoucích zápisů v jiné tabulce). Prakticky bude tedy pro každý číselník zvláštní tabulka (každý číselník bude mít svou entitu a stejně tak i entity dokumentů).
- 12 -
V praxi tedy bude ER-model použité databáze vypadat takto:
- 13 -
3.1.2.3 Klientská aplikace
Vzhledem k různorodosti vybavení počítačů na různých hnízdech bude vhodné, aby API rozhraní aplikace bylo přizpůsobitelné např. různému rozlišení monitorů. V tomto směru lze využít komponent, které obsahuje použité vývojové prostředí Delphi (Borland Developer Studio). Co se týká implementace, nepředpokládá se, že bude potřeba v první řadě do aplikace zanášet i nástroje pro správu databáze, takových je dostupných více ve free nebo opensource verzích, takže bude použito externích nástrojů. Do budoucna se předpokládá alespoň omezené množství těchto funkcí zahrnout (zálohování, obnova dat...). Dále je předpokládáno, že celá práce s daty bude postavena na objektech, které budou v sobě držet data, starat se o jejich načítání a ukládání do databáze. Bude samozřejmě snaha v maximální možné míře využít možností objektového programování a především dědičnosti. V zadání projektu je uvedeno, že by klientská aplikace měla kromě ostatních vytvářet a uchovávat i Dodací Listy, otevřené rozhraní a samotná Abra, ale umožňuje jejich generování automaticky při importu na centrále a vytváření dokladu Faktury Vydaných a Pokladních příjmů. Nebude tedy potřeba se tímto v klientské aplikaci zabývat.
3.2 Usecase diagram
- 14 -
4 REALIZACE Obě aplikace byly realizovány v jazyce Delphi .NET ve vývojovém prostředí Turbo Delphi for .NET Professional. Tento balík je také součástí Borland Developer Studio 2006 (BDS 2006). Program je zkompilován pro .NET verze 1.1 s tím, že potřebné knihovny, například Visual Component Library (VCL), která je součástí vývojového prostředí, jsou linkovány přímo ve spustitelném souboru exe. Takže pro provoz programu bude potřeba mít nainstalován .NET Framework alespoň této verze. Jedná se o dva projekty sjednocené do jedné skupiny projektů. Dále je v této skupině ještě jeden projekt obsahující některé nové a některé modifikované komponenty, které byly použity při vývoji klientské aplikace.
4.1 Serverová aplikace Jak již bylo zmíněno, tato část je napsána v programovacím jazyce Delphi for .NET za použití sady vizuálních komponent od Borlandu (VCL – Visual Component Library). K vytvoření GUI posloužil integrovaný designer použitého studia. Celá aplikace obsahuje pouze jednu unitu a definiční soubor vzhledu (vytvořený právě designerem). Celý kód této části se skládá z jedné třídy MainForm, která je potomkem TForm. Jedná se tedy o vizuální třídu, která v sobě obsahuje všechny funkcionality potřebné pro import a export dokladů. V této části by bylo použití nějaké složitější struktury objektů a dědičnosti zbytečné a spíše na škodu než k užitku. Řešení se tu snaží být co nejvíce přímočaré. Po spuštění a volání konstruktoru hlavní třídy se program pokusí připojit k Abře pomocí OLE, pokud se to nepodaří, je vyvolána výjimka a program se ukončí. Pokud proběhne připojení bez problémů, načtou se číselníky potřebné pro běh programu (především importu). Během této části dojde také k načtení konfiguračních údajů ze souboru. Během celého běhu aplikace je vytvářen log o provedených operacích, který lze uložit do souboru.
4.1.1 Nastavení Abry Vzhledem k tomu, že registrace otevřeného rozhraní neprobíhá automaticky při instalaci systému, je tedy třeba ji spustit ručně. Možnosti registrace:
• Registrace pro danou instalaci ABRA Gx se provede automaticky spuštěním programu • •
AbraOLE.exe. AbraOLELib.dll lze také zaregistrovat (resp. přeregistrovat) kdykoliv ručně a to např. pomocí příkazu "RegSvr32 AbraOLELib.dll" (bez uvozovek) do aktuálního adresáře, příp. do zadaného adresáře, je-li uvedeno s plnou cestou. Registrace potřebných součástí pro provoz otevřeného rozhraní (AbraOLE.exe i AbraOLELib.dll) na klientském počítači je rovněž možno provést v rámci agendy Nastavení klienta z dané stanice a zatržením volby instalace otevřeného rozhraní.
- 15 -
4.1.2 Nastavení aplikace Vzhledem k tomu, že veškeré udaje o dokladech jsou vytvořeny na hnízdě a přenesou se sem importem, nebude zde třeba nic nastavovat. Pouze u dokladů, ke kterým se vytváří dodací listy, bude třeba nastavit jejich řadu.
4.1.3 Importy dat Jak bylo zmíněno v analytické části tohoto textu, bude pro importy dokladů do Abry použito objektů OLE rozhraní k tomu určených. Pro každý druh importu (pokladních příjmů, faktur...) je vytvořena procedura, která načte data ze souboru ve formátu CSV a uloží je do paměti. Vzhledem k tomu, že toto je použito ve všech „importovacích“ procedurách je vytvořena také procedura, která provede načtení souborů do struktur v paměti. I v paměti jsou data uložena po sloupcích a postupně se zpracují tak, že se nejprve vytvoří objekty pro doklady. Pro příklad zde bude uveden postup pro pokladní příjem, pro ostatní doklady je obdobný. Nejprve se vytvoří instance objektu CashReceived a CashReceivedRow pomocí metody CreateObject instance třídy _Application (dále jen AGx). Dále začne cyklus vytváření dokladů. Nejprve je vytvořena instance třídy pro uchovávání dat ObjectData, ta je nejprve předvyplněna metodou PrefillValues a poté naplněna daty z tabulky v paměti. Jako další podcyklus je cyklus pro vytváření řádků. Ty se vytvářejí obdobně jako samotná hlavička, tedy vytvoří se ObjectData, předvyplní a doplní o importní data. Poté jsou tato data přidána jako nový řádek do kolekce řádků. Na konci tohoto cyklu je provedena validace dokladu, pokud proběhne bez problémů, je doklad uložen. Po uložení všech dokladů je v závislosti na nastavení programu otevřena agenda Abry, kde jsou zobrazeny právě naimportované doklady.
4.1.4 Exporty dat Protože číselníky, které podléhají exportům z centrály, jsou vlastně většinou samostatné tabulky (vyjma tabulky firem vůči tabulce adres), nejvhodnější způsob pro jejich načtení do mezipaměti bude jednoduchý SQL dotaz pomocí k tomu určené metody z AGx (SQLSelect). Data budou uložena po řádcích v NxStrings jako řetězce oddělené středníkem. Pomocí metody SaveToFile lze data uložit do daného souboru. Protože exportní soubory nebude třeba nijakým způsobem evidovat nebo archivovat, je možné, že budou mít konstantní jména a stará data se budou přepisovat novými. Ty lze pak posílat na pobočky. Jak bylo určeno dříve export bude probíhat jednoduše tak, že se data odešlou pomocí mailu na jednotlivá hnízda. Tuto činnost lze zautomatizovat pomocí nějaké externí utility sloužící k hromadnému odesílání e-mailu (například mapimail.exe). Vzhledem k tomu, že budoucí rozvoj aplikace nepočítá s tímto způsobem přenosu dat na hnízda, nebude se tato funkce integrovat přímo do aplikace.
4.2 Klientská aplikace Tato část je rovněž napsána v Delphi .NET s použitím VCL komponent a designeru BDS. V analytické části bylo zmíněno, že ke komunikaci s FireBirdem bude použito VCL komponent pro InterBase. Během programování a především testování několika tříd (např. číselník), které se v krátké - 16 -
době a velkém počtu dotazují nad připojenou databází docházelo k nahodilým výjimkám v metodách, které volaly funkce z dynamicky linkovaných knihoven pro komunikaci s FireBirdem. Tyto chyby se nepodařilo odstranit. Bylo tedy nutné hledat náhradní řešení. Nakonec byly zvoleny alternativní komponenty od CoreLab s názvem IBDAC (InterBase Data Access Components). Ty nabízí stejné možnosti jako ty z VCL s množstvím rozšířujících možností. Po použití tohoto balíčku komponent zmíněné chyby zmizely, bylo jen potřeba poněkud změnit přístup k datům a hlavně SQL dotazy, protože v tomto případě je nutno přesně definovat datové typy navrácené dotazem. Použití těchto komponent je možné i pro komerční účely s tím, že je třeba jich použít tak, že všechny knihovny budou linkovány uvnitř spustitelných souborů, s čímž je tak i tak počítáno.
4.2.1 GUI Pro splnění požadavků na univerzálnost GUI pro počítače s různými zobrazovacími schopnostmi monitorů bylo použito komponenty TGridPanel pomocí níž je možné rozdělit plochu formuláře na sloupce a řádky a do nich umístit jednotlivé kontrolní prvky. Dále bylo použito rekurzivní procedury, která při změně velikosti hlavního okna změní velikosti textů použitých podřízených kontrolních prvků. Tím je zaručeno, že se textové položky okna automaticky přizpůsobují jeho velikosti (a rozlišení). Celá aplikace je koncipována jako multi-windowed. Po spuštění se zobrazí základní okno, které je umístěno v levém horním rohu obrazovky. Na něm je obsaženo vše nejpotřebnější pro snadný a rychlý přístup ke všem nejpoužívanějším funkcím aplikace. Což jsou: vystavování a tisk dokladů a přístup k dokladům již hotovým. Dále je zde přístup k ostatním funkcím, jako jsou exporty, importy a nastavení aplikace. Okno je tedy složeno ze tří částí: Sada tlačítek pro vytvoření nových dokladů, sada tlačítek pro otevření číselníků s již hotovými doklady a menu, které obsahuje jednak položky pro stejné funkce jako mají tlačítka a další položky pro ostatní funkce důležité k chodu jako je již zmíněné nastavení aplikace a tisku a dále exporty a importy. Ovládání je díky přehlednosti velmi intuitivní a i uživatel, který program zatím neviděl, ale zná problematiku by měl být bez obtíží schopen jej použít.
- 17 -
4.2.2 Hlavní okno (základní menu) Jak již bylo zmíněno, jedná se o okno, které viditelné jako první po spuštění aplikace. Mimo jiné obsahuje i nevizuální komponenty zprostředkující připojení k databázi. Tedy hned po spuštění programu v metodě OnCreate hlavního okna proběhne nastavení parametrů a připojení k databázi. Není třeba zde nic nastavovat, neboť je předpokládáno, že databáze je umístěna ve stejném adresáři jako exe soubor a je použito embedded verze serveru v knihovně tamtéž. Rovněž informace jako jméno a heslo, pod kterým je databáze připojena, jsou statické a jedná se o klasické údaje používané při tomto druhu přístupu, tedy jako jméno SYSDBA a heslo masterkey. Pokud se připojení nezdaří, znamená to, že buď chybí soubor DB nebo knihovna pro přístup, pak nemá smysl v běhu aplikace pokračovat a je tedy přerušen po zobrazení varovné hlášky. Prvky hlavního okna jinak pouze volají metody pro zobrazení dalších oken, která už vykonávají specifické funkce, jako je třeba okno pro zadání dokladu nebo provedení exportu atp. Funkcí tohoto okna je tedy jen zprostředkovat uživateli jiná okna.
4.2.3 Okno hlavičky dokumentu (TFormDocumentHeader) Jedná se o potomka třídy TForm a o předka všech oken hlaviček dokumentů (příjemka, převodka, faktura, pokladní příjem) a zahrnuje v sobě jejich společné vlastnosti. Těmi jsou samotné zavření dokladu, uložení dokladu, tisk, otevření okna pro editaci řádků a nastavení aktuálních hodnot jako implicitní. Dále v sobě drží odkaz na instanci třídy TDocumentHeader, která je vlastně datovou třídou dokladu a bude zmíněna níže. Další společnou vlastností je metoda pro nastavení vztahu mezi datovou a vizuální částí dokladu. V této třídě je pouze jako abstraktní, protože vizuální prvky jsou vytvořeny až v samotném potomkovi této třídy. Tato třída by teoreticky mohla být abstraktní celá, protože nebude nikde použito její instance. Vzhledem k tomu, že k jejímu vytvoření byl použit také designer a existuje k ní definiční soubor vzhledu, v praxi třída abstraktní není.
- 18 -
4.2.4 Třídy pro zobrazení hlaviček Jak již bylo zmíněno, jedná se o potomky třídy TFormDocumentHeader doplněné o samotné ovládací prvky. Ty se skládají z framů, které v sobě obsahují prvky pro zadání určitých typů údajů na dokladu jako jsou: číselníkový údaj, text, datum atd. Dále je zde definována metoda pro určení vztahů mezi jednotlivými vstupními poli a atributy v dokumentu, která je definována jako abstraktní v nadřízené třídě. Okno pokladního příjmu: Z obrázku je patrná skladba dokumentu taková, že dole jsou obsaženy prvky zděděné z nadřízené třídy a v těle formu jsou prvky zastupující jednotlivé atributy dokumentu. V tomto případě jsou to Pokladna, Řada dokladů, Firma, Období, Měna, Datum dokladu a Popis. Ostatní jsou společné pro všechny hlavičkové doklady.
Ostatní doklady jsou analogicky stejné, z toho plyne, že se mění pouze obsah okna nad tlačítkem „Řádky“.
4.2.5 Okno pro zadání řádků Toto okno je společné pro všechny druhy řádků. Má v sobě definován příznak, o který typ se jedná, a podle něj pak nabízí v seznamu řádků ten, který náleží příslušnému dokumentu. V tomto okně se opět jedná o řádky pokladních příjmů. Tlačítka nahoře jsou opět společná pro všechny typy dokladů, což vyplývá z faktu, že je okno společné pro všechny doklady. V okně je patrné, že je zde držena informace o aktivním řádku, vizuálně je to vidět v levé části okna, kde je označen modře. Toho je využito například při mazání řádků nebo při určování implicitních hodnot pro předvyplnění. Po stisku tlačítka „Nový“ se volá metoda, která na základě informace o typu dokladu (resp. jeho řádku) vytvoří novou instanci framu pro tento typ řádku a zobrazí jej v okně. Odkaz na řádek jako datový dokument je definován při volání jeho konstruktoru. O všechno ostatní se stará samotný frame řádku, který funguje obdobně jako okno pro zadávání hlavičkových údajů a bude zmíněn níže.
- 19 -
4.2.6 Framy pro řádkové údaje Jedná se o framy, které se zobrazují v okně řádků dokladu a zastupují jednotlivé řádky. Principiálně fungují obdobně jako okno pro zadávání hlavičkových údajů. 4.2.6.1 Obecná třída pro řádek dokladu (TFrameDocumentRow)
Jde o potomka TFrame a předka všech vizuálních řádků dokladů. Na jeho těle je pouze panel, který barevně označuje právě aktivní řádek a PopUp menu pro zadání hodnot pro předvyplnění. Tato třída v sobě také udržuje odkaz na datovou třídu řádku a informaci o tom zda je řádek právě aktivní. Kvůli potřebě toho, aby po kliknutí na jakýkoliv prvek řádku se stal řádek aktivním, je třeba doplnit metodu, která volá metodu obecného vizuálního řádku SetRowActive, která má za úkol nastavit ostatní řádky jako neaktivní a sebe jako aktivní. Aby bylo možno toto udělat, bylo třeba aby všechny podřízené prvky (v tomto případě se jedná jen o Framy) implementovali interface, který zaručí že budou mít odkaz na řádek, který je vlastní a metodu na jeho aktivaci. Samotné prvky pak mají pouze do své metody obsluhující událost OnClick doplněno volání této metody pro aktivaci řádku, kterému náleží. 4.2.6.2 Třídy pro zobrazení řádků
Jak bylo zmíněno výše, jde o potomky TFrameDocumentRow. Jejich obsah je prakticky stejný jako tříd pro zobrazení hlaviček. Obsahuje pouze konstruktor v němž se jednak volá konstruktor nadřízené třídy a jednak přiřadí hodnoty podřízených framů (které opět zastupují jednotlivé atributy datového dokumentu). Co se týká vizuální části, jsou opět obdobně jako hlavičky doplněny o framy pro zadávání jednotlivých údajů dokumentu.
4.2.7 Framy pro zadávání údajů dokumentů Slouží pro zadávání 3 základních druhů informací: číselníkový údaj (načítá se z tabulky hodnot), datum, textová nebo číselná hodnota. Jejich společnou vlastností je, že vlevo je umístěn label s popiskem pole. 4.2.7.1 Číselná hodnota
Hlavička (TFrameNumeric) Základní třída, dědící TFrame, pro zadání číselné hodnoty je třída TFrameNumeric. V konstruktoru této třídy je definován odkaz na dokument a jméno atributu (to je společné pro všechny „vstupní framy“), dále je zde definovaná délka čísla (v cifrách) a délka desetinné části. Další společná metoda je metoda SetDocument, která má podobné parametry jako konstruktor a volá se v něm. Během této metody se volá i metoda FillFromDocument, která nastaví zobrazený údaj podle údaje v dokumentu (to je důležité zejména při načtení dokumentu z databáze). Navíc je zde omezeno zadávání údajů tak aby sem šlo psát pouze čísla, desetinný oddělovač a to jen do délky zadané v konstruktoru. Řádek (TFrameNumericRow) Jedná se o přímého potomka TFrameNumeric, kterého rozšiřuje pouze o dříve zmíněnou implementaci interface IFrameRowEmbed. Tzn. že musí obsahovat metodu pro nastavení procedury, která má za úkol nastavit nadřízený řádek jako aktivní a dále rozšiřuje metody pro - 20 -
obsluhu událostí OnClick prvků, které jsou na tomto framu umístěny. 4.2.7.2 Textová hodnota (TFrameDescription a TFrameDescriptionRow)
Vlastnosti této třídy jsou podobné těm z framu pro zadávání číselných hodnot. Rozdíl je v možnosti určit množinu znaků, které možné sem lze zadat. Třída pro řádkový údaj se opět liší jen v implementaci interface pro aktivaci řádku na kterém je umístěna. 4.2.7.3 Datum (TFrameDateTimePicker)
Na svém těle obsahuje komponentu TDateTimePicker, která uživateli zprostředkuje vizuální kalendář, kde je možno snadno vybrat datum. Je možné zadat ho i na klávesnici. Stejně jako na výše zmíněných framech obsahuje odkaz na dokument a atribut, který se mění podle nastavených hodnot. Tento frame nemá svou řádkovou podobu, protože jí nebylo zapotřebí. 4.2.7.4 Číselníková položka
Bázová třída číselníkové položky (TFrameRoll) - Je potomkem třídy TFrame a předchůdcem všech číselníkových framů. Obsahuje v sobě všechny metody a funkce potřebné pro práci s číselníkovými údaji. Jsou to jednak opět odkaz na dokument a jeho atribut, stejně jako u všech předchozích. Dále zde jsou metody pro obsluhu všech důležitých událostí v dědících třídách. Hlavičková třída číselníkové položky (TFrameRollHeader) - Dědí bázovou třídu číselníkových položek a doplňuje ji o vizuální komponenty pro zobrazení číselníkových údajů. Tato konkrétně obsahuje tlačítko pro vyvolání okna číselníku, editační okno pro ruční zadání údaje (zpravidla atribut CODE) a dva labely, jeden statický pro údaj o jakou hodnotu (atribut) se jedná a jeden dynamický, kde se zobrazuje informace o vybraném záznamu (nejčastěji název, tj. atribut NAME). Dále se liší od svého předka o doplněný konstruktor, ve kterém se doplní odkazy na vizuální komponenty pro použití v nadřazené třídě. „Odlehčená“ hlavičková třída číselníkové položky (TFrameRollHeaderEmbed) - Prakticky stejná jako předchozí třída s tím rozdílem, že nemá editační pole pro ruční zadání z klávesnice a hodnota se zde musí vybrat z tabulky hodnot (řádků). Řádková třída číselníkové položky (TFrameRollRowEmbedded) – Zjednodušená verze pro výběr na řádku, kde je třeba šetřit místem. Obsahuje pouze editační pole a tlačítko pro otevření vizuálního číselníku.
4.2.8 Třídy pro zobrazení číselníků (TFormRoll) Tato třída je potomkem třídy TForm, primárně je to vizuální třída pro zprostředkování okna pro výběr údaje z databázové tabulky. Jak je vidět v náhledu okna, obsahuje grid pro zobrazení databázových údajů a funkce pro vyhledávání a třídění hodnot podle jednotlivých sloupců.
Jak bylo zmíněno dříve, odkaz na potomky této třídy si v sobě udržují framy číselníkových - 21 -
položek v okně dokumentu. Všechny metody a atributy jsou definovány v bázové třídě TFormRoll a její potomci se od ní liší prakticky jenom v konstruktoru, kde se do řetězcové hodnoty pro název tabulky příslušný řetězec, který je použit pro definici zobrazených dat. Mimo této funkce splňuje ještě mnoho funkcí nevizuálních. Tato třída je vlastně jeden ze základních stavebních kamenů klientské aplikace. Jednou z dalších nevizuálních funkcí je „dokončení“, kdy se podle zadaného řetězcového parametru a názvu sloupce nabídne první hodnota, která začíná tímto parametrem. Z dalších například dohledání hodnoty ve sloupci podle identifikátoru nebo naopak dohledání identifikátoru podle hodnoty v jiném sloupci (např. ID podle kódu apod.).
4.2.9 Vizuální třídy pro Export/Import Export (TFormExport) Je to okno, které v sobě obsahuje všechny funkce potřebné pro export dat, která se následně odesílají na centrálu. Tato třída kromě té viditelné části, obsahuje i funkce pro uložení dat do souboru a update databáze (doklady se označí jako exportované).
- 22 -
Import (TFormImport) Protože všechny soubory jsou ve stejném formátu a jejich import je tedy podobný, obsahuje tato třída metody loadCsvFile (nutno připomenout, že CSV není zcela správně, protože v tomto formátu by se mělo jednat o hodnoty oddělené čárkami, v našem případě se jedná o středníky) pro načtení hodnot ze souboru do datových struktur (TStringList). A dále metodu Import, která má za parametry: array of TStringList a jméno tabulky kam se budou data importovat. Díky těmto metodám se kód na import souborů zmenší na zadání názvu tabulky a souboru. Jak je vidět v náhledu okna, existuje možnost „Smazat tabulky před importem“. V tomto případě se nejprve obsah tabulek číselníků zcela vymaže a poté se naplní daty. Aby bylo toto možné, je třeba mít provedeny všechny exporty a tabulky dokladů vymazané (to se dělá v okně provedených exportů, viz. níže). Pokud chceme uchovávat historii dokladů (tedy i ty již exportované) existuje i možnost updatovat tabulky číselníků. To se děje tak, že se všechny záznamy označí jako skryté (nezobrazují se v číselnících), ale jsou stále součástí databáze. Provedené exporty (TFormOldExport) Pro zobrazení provedených exportů je v databázi aplikace vytvořen pohled, který vypíše, co a kdy bylo exportováno a o kolik dokladů se jednalo. Lze tady vybraný export „Obnovit“, to znamená, že se doklady které byly v rámci tohoto exportu označené jako exportované a uložené do souboru vrátit zpět do „aktivních doklad“. Toho lze využit například k opakovanému vytvoření exportních souborů. Další možností, která se dá provést s již provedenými exporty, je jejich smazání. Tímto způsobem se data natrvalo odstraní z databáze a již je nelze vyvolat zpět.
4.2.10 Třídy pro uchování dat 4.2.10.1 Atribut (TAttribute)
Je to základní třída pro uchování dat dokumentu. Slouží k uchování jednoho atributu dokumentu, podporuje všechny základní typy jako celé číslo, reálné číslo, logická hodnota (ano/ne), případně odkaz na seznam řádků, dále v něm lze uchovat prakticky jakýkoliv jiný typ jako TObject, - 23 -
je ale třeba si explicitně pamatovat o jaký typ se jedná. Z atributů jsou důležité dva a to název atributu a hodnota, ta je typu TObject a lze do ní tedy uložit cokoliv. Metody třídy jsou standardní pro podobný typ funkcionality a jsou to metody GetValue a GetValueAsTyp a přetížená metoda SetValue. Další zajímavé metody jsou napsány pro podporu práce s databází a jsou to GetUpdateString a GetInsertString, které na základě typu a jména atributu vrátí řetězec pro operaci nad databází, tedy například řetězcový údaj opatří apostrofy apod. (např. vrátí NAME = 'jméno' pro update string). Toho je později hojně využito při ukládání a opravách dokumentů v databázi. 4.2.10.2 Seznamy (TAttributeList a TDocumentList)
Tyto třídy slouží pro evidenci seznamů atributů (v třídě TDocument) a nebo dokumentů (řádky na hlavičkách dokladů). Jsou prakticky shodné až na použité typy. Podporují procházení cyklem typu foreach. Dále obsahují standardní metody listů jako Add, Delete, Get, Count a GetEnumerator. Kvůli metodě GetEnumerator jsou ještě vytvořeny třídy TDocumentEnumerator a TAttributeEnumerator. 4.2.10.3 Bázová třída dokumentu (TDocument)
Jak je vidět na obecném schématu v analytické části této práce, je tato třída předkem všech datových tříd programu a to jak řádků tak i hlaviček a drží v sobě všechny jejich společné vlastnosti a metody. Pro uchování dat je použit seznam atributů. Důležitými atributy (jedná se přímo o atributy třídy, nejsou tedy součástí AttributesList) této třídy jsou příznaky Deleted a Loaded, podle kterých se pozná, jak s jednotlivými objekty zacházet při ukládání dokumentu. Při vytváření nového dokumentu, je jeho příznak Loaded nastaven na False a při ukládání se tedy provede jeho insert do databáze. Pokud ovšem načteme dokument již dříve vytvořený, jeho příznak Loaded je nastaven na True a při ukládání je proveden jeho update. Obdobně je to s příznakem deleted, pokud označím řádek jako smazaný (v aplikaci se jeví tak, že zmizí a je smazán), smaže se ale až ve chvíli, kdy takový doklad uložím a provede se delete nad databází. Aby bylo možné mít některé metody definovány již na této úrovni, je potřeba si ještě držet atributy jako jméno tabulky související s aktuálním typem dokumentu a jméno jeho generátoru. Podobně jako samotné atributy mají i dokumenty metody pro získání SQL příkazů. Tentokrát se jedná o kompletní dotazy (resp. příkazy) tzn. že vrací celé SQL včetně klíčových slov jako UPDATE, DELETE a INSERT (např. DELETE FROM PRIJEMKYRADKY WHERE ID=51). Pro Insert a Update se požívají metody atributů pro získání části příkazu. Aby toto bylo možno nesou atributy stejná jména jako sloupce v jednotlivých tabulkách, což celou věc značně ulehčuje. Metody pro Insert a Update jsou navíc abstraktní a jejich vlastní definice je daná až v koncových třídách, které zastupují jednotlivé dokumenty a řádky, kde je známo, jaké atributy jsou v nich obsaženy. Aby mohly mít všechny třídy stejný konstruktor, definovaný již v této třídě, je tu definována také abstraktní metoda CreateColumns, která má za úkol naplnit AttributesList příslušnými atributy a je „fyzicky“ definována na úrovni nejvzdálenějších potomků této třídy (tedy samotné třídy koncových dokumentů jako příjemka atd.). Další abstraktní metody jsou například LoadFromDB s parametrem id, která načte a naplní sebe sama daty z databáze podle předaného identifikátoru a LoadDefaults, která načte hodnoty pro předvyplnění číselníkových údajů. Proti tomu je tu metoda pro uložení aktuálního záznamu jako implicitního. Metody pro práci s implicitními hodnotami nejsou abstraktní. - 24 -
4.2.10.4 Bázová třída hlaviček (TDocumentHeader)
Jak je patrné z názvu, jde o předka všech hlaviček dokumentů. Na této úrovni je definovaná metoda pro uložení dokumentu do databáze, která právě na základě příznaků Loaded a Deleted upraví současnou databázi tak, aby odpovídala provedeným změnám. Je to prováděno tak, že metoda nejprve vytvoří set řetězců z nichž každý obsahuje dílčí SQL příkaz pro vytvoření, update nebo smazání dokladu (resp. jeho řádku). Ty se pak v rámci jedné transakce provedou. Další společnou vlastností hlaviček je tisk dokumentů. Je zde tedy definován název reportu, který se použije pro tisk (ten naplní až potomek této třídy ve svém konstruktoru). Dále také metoda pro naplnění virtuální tabulky pro vyplnění tiskového reportu (ta je opět virtuální). Pro export dat do CSV souboru je zde definovaná metoda ExportToCsv, která vrátí TStringList s řádky souboru reprezentující data dokumentu. 4.2.10.5 Bázová třída řádků (TDocumentRow)
Tato třída definuje oproti svému předku pouze metodu GetSQL, která na základě příznaku Loaded vrátí buď řetězec pro Update nebo Insert. Dále přepisuje metodu pro načtení dat z databáze na základě parametru identifikátoru. 4.2.10.6 Vlastní třídy hlavičkových dokumentů
Jde o třídy TCashReceived, TReceiptCard, TIssuedInvoice, TOutgoingTransfer (pokladní příjem, příjemka na sklad, faktura vydaná, převodka výdej). Tyto třídy pouze přepisují abstraktní metody svých předků. Jedná se o tyto: 1) FillVirtualTables – naplní tabulky předané jako parametry daty pro tiskový report 2) GetSQLUpdate, GetSQLInsert – vrátí řetězec s příslušným SQL příkazem 3) CreateColumns – vytvoří atributy dokumentu 4) FillFromSQL – tato metoda nebyla zatím zmíněna, ale jako parametr má instanci třídy TIBCSQL, která je naplněna daty po SQL dotazu a obsahuje všechna data pro definici atributů dokumentu. 5) GetRowFromDB – má jako parametr id řádku, který si podle svého typu načte a vrátí. 4.2.10.7 Vlastní třídy řádkových dokumentů
Obdobně jako hlavičky pouze přepisují abstraktní metody předků (názvy tříd jsou analogické k hlavičkám TCashReceivedRow pro řádek pokladního příjmu atd.) Přepsané metody jsou CreateColumns, FillFromSQL, GetSQLUpdate, GetSQLInsert a funkce mají stejné jako u hlaviček.
- 25 -
5 TESTOVÁNÍ 5.1 Jednotkové testy Tyto testy slouží k ověření bezchybného chodu částí celého programu (modulů). Na základě různých vstupů a nastavení by měly být otestovány všechny průchody uvnitř modulu. V této fázi na sobě jednotlivé moduly nejsou nijak závislé. Je tedy možno je testovat v libovolném množství v jeden okamžik (v tomto případě to neplatí, protože na testování není k dispozici tým testerů). Tyto testy probíhaly v průběhu vývoje po ukončení práce na některé z částí programu. Například po dokončení číselníku, bylo testováno zda a jak funguje při různých vstupech (v tomto případě to byla data z FireBirdu). Dalšími jednotkami pro testování byly například jednotlivé vizuální třídy (například framy pro zobrazení a změnu dat dokladu). Je potřeba dodat, že většina tříd pro svůj chod potřebuje mít tzv. „kde fungovat“ z čehož plyne že tyto testy se prolínaly i s testy integračními a naopak.
5.2 Testy integrace modulů (Integrační testy) Jsou to testy, kde k hlavním třídám postupně přibývají vedlejší jim podřízené. Po přidání takové části je vždy zapotřebí otestovat správnou funkčnost v rámci nadřízeného „modulu“. Takovéto testy lze provádět dvěma strategiemi – do hloubky a do šířky. V rámci těchto testů ještě probíhají testy tzv. regresivní, které mají ověřit, zda opravením některých chyb nevznikly chyby jiné (ty se nazývají zavlečené chyby). Toto testování taktéž probíhalo v průběhu vývoje aplikace a jak bylo zmíněno výše prolínalo se s testy jednotkovými (resp. pokud byla část aplikace testována jednotkově mohl zároveň probíhat i test integrační). V rámci většího problému (řešeného týmem) by toto mohl být problém, ale vzhledem k tomu, že zde se jedná o aplikaci vyvíjenou jedním vývojářem, jednalo se spíše o zjednodušení celé věci.
5.3 Validační testy Validační testy se provádějí proto, aby se ověřilo, zda produkt vyhovuje požadavkům zákazníka, které specifikoval při zadání. U tohoto druhu testů by bylo nejvhodnější, aby si produkt mohl testovat sám objednatel (resp. zákazník) za asistence vývojáře. V našem případě, to není možno, neboť v průběhu procesu vývoje aplikace došlo ke komplikacím, které toto znemožnily. Díky tomu, že je k dispozici podrobné zadání projektu a potřeby firmy jsou dobře známy, bylo možné na jejich základě validační testy provést. Validační testování bylo prováděno tím způsobem, že se simulovaly procesy které představují použití programu v praxi. Tedy zadávaní dokladů s různými vstupy, jejich export a import na centrále, export číselníků z centrály a import na pobočce apod.
5.4 Systémové testy Jde o sérii testů, které by měly nasimulovat situace, kdy dojde například k výpadku proudu za provozu. Neoprávněné vniknutí do systému, nebo různé další pokusy o „nabourání“ do systému. Tyto testy prováděny nebyly, vzhledem ke konceptu aplikace a její funkci je nepravděpodobné, že by jich bylo potřeba. Vzhledem k tomu, že nějaká větší zabezpečení systému nebyla součástí zadání, nebylo s nimi počítáno a aplikace je tedy neobsahuje. Tento druh testování - 26 -
by tedy neměl smysl.
5.5 Výsledky testování (Shrnutí) Výsledkem testování je aplikace, která je použitelná v praxi. Bohužel se zatím ale neplánuje její ostré nasazení a zatím není ani jasné zda-li k němu vůbec dojde. Pokud by se tak stalo, je počítáno ještě s jednou fází Validačního testování, kdy by se aplikace nasadila na jednom nebo více hnízdech, kde není tak velký provoz (řádově do deseti dokladů denně) paralelně se stávajícím systémem, aby bylo možno odhalit a doladit chyby, které mohly v programu zůstat. Obecně je testování jednou ze slabších míst tohoto projektu, neboť není, ani v průběhu vývoje nebylo dostatek zdrojů pro jeho realizaci v množství v jakém by bylo potřeba. Aplikace splňuje cíle vytyčené v zadání projektu. V současné době je jednoznačně použitelná a do vysoké míry i otestovaná. Většina chyb byla určitě odhalena a odstraněna již v průběhu vývoje. Chyby, které v aplikaci nejspíš zůstaly se předpokládají spíše v částech, které bude možno odhalit převážně v praktickém provozu. Praxe také jistě odhalí nedostatky i jiného ražení, než je samotná funkcionalita systému.
- 27 -
6 ZÁVĚR Při vývoji jsem se v práci zabýval analýzou samotného problému, v první řadě to byly možnosti implementace, kde se ukázalo, že je mnoho způsobů jak celý problém vyřešit. Výběr způsobu implementace byl značně ovlivněn omezenými možnostmi firmy Paliva Písek a.s., které vyplývají už ze samotného zadání projektu. Byly zmíněny dva způsoby řešení: jedno kdy máme přímé spojení na centrálu a druhé kde jsou pobočky off-line. Přímé spojení by bylo ve všech ohledech jednodušší pro uživatele. Bohužel už z potřeb a možností firmy a částečně i ze zadání vyplývá, že tento způsob nebude pro splnění záměru ten pravý. Výsledkem bakalářské práce jsou dvě aplikace, které můžou nahradit současný systém použitý ve firmě Paliva Písek a.s. Jedna pro serverovou a jedna pro klientskou část. Pro napsání serverové části bylo v první řadě potřeba se dobře seznámit s obsahem a možnostmi otevřeného rozhraní systému Abra, vzhledem k tomu, že je velmi dobře a podrobně zdokumentováno a již jsem s ním měl zkušenosti, nebyl toto velký problém. Tato část byla napsána jako první, protože je sama o sobě mnohem jednodušší než je klient a díky tomu pak bylo i možné pracovat s reálnými daty z Abry, protože je pomocí ní šlo vyexportovat. Stěžejní částí je bezpochyby část klientská, která má na starosti všechny důležité funkcionality. Při jejím vývoji byla zapotřebí mnohem podrobnější analýza toho, co vlastně bude potřeba napsat a udělat. První vize byla jednoduše taková, že se vytvoří jednoduché přehledné GUI a všechny funkcionality, se napíší pro každý ovládací prvek zvlášť. Takové řešení by bylo určitě rychlé a jednoduché, ale jakákoliv následná úprava by vyžadovala přepisování spousty kódu a to by bylo nežádoucí, zvlášť pokud počítáme s následnými úpravami (Mimo jiné i opravy chyb v tomto druhu řešení s sebou velmi často přinášejí potíže ve formě tzv. zavlečených chyb). Druhá vize byl poněkud opačný extrém, kdy by se vytvořily univerzální datové třídy, které se podle svých vlastností (atributů) samy načtou z databáze a nad nimi budou existovat opět univerzální vizuální třídy, které budou zprostředkovávat uživateli data. Z počátku, se toto jevilo jako dobré řešení, ale jeho napsání by si vyžadovalo neúměrně mnoho práce v poměru k potřebám programu. Výsledkem tedy byl kompromis, mezi oběma zmíněnými řešeními, kde jsou datové třídy univerzální (z nich se pak dědí konkrétní) a vizuální jsou pouze konkrétní. Další důležitou částí byl návrh a implementace úložiště dat, jedná se o jednoduchou databázi, která je popsaná v analýze řešení. Samotné programování, už bylo pouze uvedení zde a v zadání popsaného do praxe. Vzhledem k tomu, že již zhruba od poloviny vývoje aplikace bylo téměř jisté, že nebude nasazena do ostrého provozu, byla tedy dokončena jen pro účel této bakalářské práce. Z toho plyne řada nedostatků, které jsou na aplikaci patrné. V první řadě je třeba zmínit, že byl stoprocentně dodržen záměr celého projektu, to znamená, že byly splněny všechny cíle a požadavky na aplikaci. Nedostatkem jednoznačně zůstává GUI, jehož podstata je spíše funkční a je tedy zaměřeno především na splnění zadání. Pokud by ale došlo k tomu, že se program bude skutečně nasazovat v praxi, není problém udělat pár úprav, kterými by byl tento nedostatek eliminován (toto by probíhalo za asistence potenciálního koncového uživatele). K dalším faktům, která brání nasazení programu do ostrého provozu, patří bezpochyby to, že návrh na program byl vytvořen v době, kdy byla samotná Abra ve verzi 5 a oproti nynější verzi 7 jí mnoho chybělo. V současné době by bylo výhodnější, nasadit verzi Abry určenou pro více hnízd (poboček) s takovými omezeními, která by pokrývala potřeby hnízd. Nespornou výhodou ovšem zůstává, že v našem řešení nedochází k replikaci celé databáze, ale pouze její části potřebné k provozu.
- 28 -
7 SEZNAM POUŽITÉ LITERATURY Knihy: C# V KOSTCE – Pohotová referenční příručka (Peter Drayton, Ben Albahari & Ted Neward) Interbase/Firebird – Tvorba, programování a správa databáze (Pavel Císař) Internetové stránky: http://sin.korinek.name/Tests.html http://www.zive.cz/ http://forum.builder.cz/list.php?18 http://www.abra.eu/
Nápovědy: Pro systém Abra Gx (AbraG3.chm) Dokumentace k OLE Abra Gx (G3Doc.chm) K Borland Delphi for .NET Dokumentace k Microsoft .NET
- 29 -
8 Přílohy 8.1 Obsah přiloženého CD ROOT ABRA_CHM dokumentace k účetnímu systému ABRA a k jeho OLE ABRA_INS instalační balíčky Abry G2 a G3 BP obsahuje tuto zprávu (MS Word,Adobe Acrobat,OpenDocument) FB instalační balík FireBird pro MS Windows a Linux PRG zkompilované programy pro server a klienta včetně klientské DB SC zdrojové kódy pro obě aplikace a pomocnou knihovnu
- 30 -