VYSOKÁ ŠKOLA POLYTECHNICKÁ JIHLAVA Katedra elektrotechniky a informatiky
Systém provozu restaurace bakalářská práce
Autor: Martin Doležal Vedoucí práce: PaedDr. František Smrčka, Ph.D. Jihlava 2011
Abstrakt Moje bakalářská práce se zabývá vývojem systému pro provoz konkrétní menší restaurace. Systém je naprogramován pomocí jazyka PHP, značkovací jazyk jsem použil XHTML, grafické rozhraní je řešeno pomocí kaskádových stylů CSS a funkce na kontrolu formulářů jsem vyřešil pomocí JavaScriptu. Jde o systém, kde bude mít majitel veškeré informace o vedení skladu, jeho historii, možnost vytvoření a tisku čárového kódu pro položky, které nemají etiketu s čárovým kódem a v neposlední řadě také informace o odpracovaných hodinách zaměstnanců. Naskladňovat, hledat či prodávat položky lze jak čtečkou čárových kódů, tak pomocí počítače a do budoucna je tento systém připraven na ovládání pomocí dotykového displeje.
Klíčová slova PHP, XHTML, CSS, JavaScript, systém, phpMyAdmin, databáze, čárový kód, fpdf, PDF
Abstract My bachelor thesis deals with the development of a system for running a specific small restaurant. The system is programmed in PHP, I used the markup language XHTML, graphics interface is done by CSS, and the function which controls forms is programmed in JavaScript. It is a system where the owner will have all information about stock management, its history, a possibility to create and print bar codes for the items which don´t have a label with a bar code, and last but not least, the owner will have information about how many hours employees worked. Storing, finding or selling items can be done by bar code readers or by a PC and the system is prepared for future control by a touch screen.
Poděkování Rád bych poděkoval vedoucímu mé bakalářské práce, panu PaedDr. Františku Smrčkovi, za udělení užitečných rad, čas se mnou strávený a jeho věcné připomínky při tvorbě mé práce.
Prohlášení Prohlašuji, že předložená bakalářská práce je původní a zpracoval jsem ji samostatně. Prohlašuji, že citace použitých pramenů je úplná, že jsem v práci neporušil autorská práva (ve smyslu 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ů, v platném znění, dále též „AZ“). Souhlasím s umístěním bakalářské práce v knihovně VŠPJ a s jejím užitím k výuce nebo k vlastní vnitřní potřebě VŠPJ . Byl jsem seznámen s tím, že na mou bakalářskou práci se plně vztahuje AZ, zejména § 60 (školní dílo). Beru na vědomí, že VŠPJ má právo na uzavření licenční smlouvy o užití mé bakalářské práce a prohlašuji, že s o u h l a s í m s případným užitím mé bakalářské práce (prodej, zapůjčení apod.). Jsem si vědom toho, že užít své bakalářské práce či poskytnout licenci k jejímu využití mohu jen se souhlasem VŠPJ, která má právo ode mne požadovat přiměřený příspěvek na úhradu nákladů, vynaložených vysokou školou na vytvoření díla (až do jejich skutečné výše), z výdělku dosaženého v souvislosti s užitím díla či poskytnutím licence. V Jihlavě dne ..................................................... Podpis
Obsah
1 2
Úvod ......................................................................................................................................... 7 Analýza specifikace ................................................................................................................ 9 2.1 Modul kategorie a zboží .................................................................................................. 11 2.2 Modul historie zboží ........................................................................................................ 11 2.3 Modul nové směny, prodeje a ukončení směny .............................................................. 12 2.4 Modul zaměstnanci a jejich výplat .................................................................................. 12 3 Návrh řešení .......................................................................................................................... 14 3.1 Existující známá řešení .................................................................................................... 14 3.2 Použité programovací prostředky .................................................................................... 14 3.2.1 MySQL ..................................................................................................................... 14 3.2.2 PHP ........................................................................................................................... 15 3.2.3 JavaScript ................................................................................................................. 16 3.2.4 XHTML .................................................................................................................... 16 3.2.5 CSS – kaskádové styly ............................................................................................. 18 3.3 Použité volně dostupné prostředky .................................................................................. 18 3.3.1 Knihovna FPDF........................................................................................................ 18 3.3.2 Barcode Generator.................................................................................................... 19 4 Popis implementace .............................................................................................................. 21 4.1 Databáze .......................................................................................................................... 21 4.2 Vytvořená struktura kořenového adresáře ....................................................................... 22 4.3 Popis jednotlivých položek adresářů ............................................................................... 22 4.4 Jednotlivé moduly............................................................................................................ 29 4.4.1 Kategorie .................................................................................................................. 30 4.4.2 Zboží......................................................................................................................... 31 4.4.3 Historie zboží ........................................................................................................... 32 4.4.4 Založení nové směny a prodej položek .................................................................... 33 4.4.5 Konec směny ............................................................................................................ 34 4.4.6 Zaměstnanci ............................................................................................................. 35 4.4.7 Evidence výplat ........................................................................................................ 35 5 Výsledky testování ................................................................................................................ 37 6 Srovnání s již hotovými řešeními ........................................................................................ 38 6.1 Poznatky z praxe .............................................................................................................. 38 6.2 Poznatky z internetu ........................................................................................................ 38 7 Závěr ...................................................................................................................................... 39 7.1 Splnění cílů ...................................................................................................................... 39 7.2 Problémy a jejich řešení .................................................................................................. 39 7.3 Možnosti rozšíření mé práce............................................................................................ 40 Seznam použité literatury ............................................................................................................ 41 Seznam obrázků ........................................................................................................................... 42 Seznam použitých zkratek ........................................................................................................... 43 Slovník pojmů ............................................................................................................................... 44 Seznam příloh ............................................................................................................................... 45
1 Úvod Volbu mé bakalářské práce ovlivnil především výběr školní praxe, kde jsem se více setkal s praktickým programováním dynamických webových stránek a různých jiných aplikací pomocí jazyka PHP. Samozřejmě jsem před touto praxí absolvoval předmět Tvorba www aplikací, takže pro mě PHP nebylo nic nového. Použití v praxi je však vždy trochu jiné. Během této praxe jsem se seznámil s majitelem místní restaurace, který mě nedávno oslovil s prosbou o vytvoření systému, který bude evidovat chod jeho restaurace. Toto téma se mi velice zalíbilo nejen proto, že školou nabízená témata mě moc nezaujala nebo byla obsazená, ale hlavně kvůli mé zálibě v programování internetových aplikací, ve kterých bych se i nadále rád zdokonaloval. Cílem této práce je vytvořit jednoduchý a přehledný systém, který bude majiteli poskytovat informace o vedení skladu a jeho historii (kdo a kdy pohyboval s určitou položkou). Sklad bude také obsahovat funkci pro hlídání stavu zboží. Majitel tak bude mít přehled, kterých položek má dosti, a které je potřeba dokoupit. Další funkcí bude možnost vytvoření a tisku čárového kódu a v neposlední řadě také informace o odpracovaných hodinách zaměstnanců. Systém nebude přístupný veřejnosti. Přístup do něj bude možný pouze po zadání přihlašovacího jména a hesla, které bude šifrováno podle algoritmu MD5. Uživatelé budou mít dvě různá oprávnění, podle nich budou moci provádět jednotlivé úkony. Do hlavní části programu s veškerými funkcemi a právy bude mít oprávněný přístup pouze majitel. Ten bude moci vytvářet či mazat položky, editovat skladové položky, jako je název, cena zboží. Bude moci přidávat a editovat zaměstnance nebo zaměstnance mazat. Zaměstnanec se na začátku směny přihlásí a bude moci pouze prodávat zboží, popřípadě vytvořit a vytisknout čárový kód. Na konci směny se odhlásí. Systém mu vypočítá tržbu, kterou má odevzdat zaměstnavateli a odpracované hodiny. Poté zaměstnanec uvidí svoje odpracované hodiny v modulu evidence výplat. Jelikož chce mít zadavatel snadný přístup k tomuto systému odkudkoli, volba programovacího jazyka PHP byla jasná. Jako značkovací jazyk jsem zvolil XHTML, některé funkce budou tvořeny pomocí JavaScriptu a grafický vzhled bude vytvořen pomocí kaskádových stylů CSS a s nižším rozlišením než 1024 na 768 pixelů se nebude počítat. Jako zdroj dat bude použit databázový systém MySQL. Tyto programovací prostředky jsem zvolil také pro jejich širokou 7
podporu u webhostingů a jak jsem již předeslal na začátku, mám s těmito programovacími prostředky bohaté zkušenosti, které bych rád uplatnil při tvorbě tohoto systému. Systém by měl být validní a měl by být umístěn na serveru http://www.hospoda.stonecity.cz, tento server je provozován na operačním systému Linux.
8
2 Analýza specifikace Po oslovení zadavatelem s požadavkem na vytvoření tohoto systému proběhlo několik konzultací. Na těchto konzultacích byly sděleny požadavky a představy na funkce systému, ze kterých vznikl první návrh ER-diagramu. Tento diagram se samozřejmě po každé konzultaci trochu měnil. Po základních konzultacích tedy vznikl následující ER-diagram.
Obrázek 1 ER - diagram
Jak je vidět z obrázku, asi nejdůležitější tabulkou tohoto ER-diagramu je tabulka zbozi. V této tabulce evidujeme název a cenu položek, primárním klíčem je atribut ean. Z důvodu používání 9
čtečky čárových kódů byl pro pohyb položek zvolen jako primární klíč čárový kód položky. Tato tabulka je spojovaná hned se třemi dalšími tabulkami. Spojení s tabulkou kategorie, bude ještě vysvětleno (viz kapitola 3.2.1). V Tabulce kategorie kromě názvu kategorie ještě evidujeme typ kategorie. Zadavatel si přál rozdělit restauraci na kuchyň a bar. Pod atributem typ v tabulce kategorie se tedy nachází bar a kuchyň. Pro tyto položky je zaveden atribut typ také pro možné budoucí rozšíření. Například by se mohl systém v budoucnu rozšířit o evidenci diskotéky nebo třeba vinotéky a i tyto sektory by se daly evidovat zvlášť. Tabulka sklad eviduje historii pohybu zboží. Název sklad může být tedy trochu matoucí. Ukládá se zde veškerý pohyb položek. Je tedy zapotřebí pouze jednoduchého SQL dotazu pro zjištění celé nebo jen částečné historie dané položky. Do atributu kdo se ukládá jméno a příjmení osoby, která s položkou něco prováděla. Na první pohled by se tedy zdálo, že má být tabulka sklad spojená s tabulkou zamestnanec. Spojení těchto tabulek je ve skutečnosti zbytečné, protože nepotřebujeme další informace z tabulky zamestnanec, a tak je tento krok vyřešen programově. Dalším spojením je tabulka zboží a prodej. V tabulce prodej je zřejmě nejasný atribut stav. Do tohoto atributu se ukládá stav prodaného zboží. Pokud by bylo zboží stornováno (prodej položky by byl zrušen), změní se hodnota tohoto atributu, což uvidíme při ukončení prodeje. V tabulce smena evidujeme mimo jiné datum začátku a konce směny a tržbu na baru a v kuchyni. Tyto sektory, jak jsem již uvedl, si přál majitel oddělit a tržbu počítat pro každý sektor zvlášť. Zajímavými atributy v tabulce zamestnanec jsou snad jen atributy aktivni a pristup. V atributu aktivní je uloženo, zda je zaměstnanec stále mezi aktivními zaměstnanci. Pokud není, zamezí se jeho přístupu do systému. Na podobném principu funguje i atribut pristup. Pokud nemá uživatel přístup, může využívat pouze některé funkce. V tabulce vyplata je mimo jiné sloupec datum_vyplaty pro držení historie výplat. Je to systém opravdu šitý na míru pro tuto konkrétní restauraci, ve které se dosud veškeré pohyby zboží zaznamenávaly na účtenky a jiné kousky papíru. Tyto papíry se pak také občas ztratily. Musela se tedy provádět inventura zboží a jiné úkony s tím spojené. Po zavedení systému tedy veškeré problémy s papírováním odpadnou. Zadavatel dosud neměl žádnou zkušenost s podobným programem, proto si ze začátku nedokázal představit, co by všechno jeho systém mohl umět. Jeho představa však byla postupnými konzultacemi naplněna. Dohodli jsme se tento
10
systém rozdělit do několika oddílů (modulů). Před započetím práce na každém tomto modulu byly vždy upřesňovány konkrétní požadavky zadavatele.
2.1 Modul kategorie a zboží Prvním požadavkem bylo rozdělení zboží do různých kategorií. A také tyto kategorie roztřídit do sekce kuchyň a bar. Samozřejmě zde bude možnost vytvoření nové kategorie, kde se bude evidovat název a typ kategorie. Názvy kategorií půjdou editovat a mazat. Typ kategorie není potřeba editovat. Je dosti nepravděpodobné, že se například kategorie Nealko v budoucnu přesune ze sekce Bar do sekce Kuchyň. V modulu zboží půjdou vytvářet nové položky (zboží). Vytváření zboží půjde přes čtečku čárových kódů i pomocí klávesnice. Bude se zde evidovat cena, název zboží, do jaké kategorie zboží spadá a jaký má čárový kód. Editace názvu a ceny bude samozřejmě možná. Editování nebo mazání bude také možné. Je však pochopitelné, že pokud bude zboží již někdy prodáno, smazání možné nebude. Pokud by bylo zboží smazáno, ztratili bychom přehled o jeho historii. Editace a mazání bude možné v každém dalším modulu, kde je tato možnost. Oprávnění k tomuto úkonu bude mít pouze majitel. Další opakující se funkcí, je vkládání čárového kódu pomocí čtečky čárových kódů, a samozřejmě počítačem. Tuto funkci mají oprávnění používat i zaměstnanci. Jelikož v restauraci dochází k prodeji zboží, které nemá etiketu s čárovým kódem, je zapotřebí vytvořit funkci na tvorbu a tisk čárového kódu. Tato funkce zde bude k dispozici. Seznam zboží by měl jít filtrovat podle kategorie. Mělo by jít vyhledat zboží pomocí čárového kódu. Hlavně kvůli budoucí editaci nebo tvorbě a tisku čárového kódu konkrétního zboží.
2.2 Modul historie zboží Pro kontrolu správného pohybu zboží zde bude zakomponován modul historie zboží. Každé zboží bude mít svojí historii pohybu. Pro představu tento modul bude plnit funkci skladu a historie pohybu zboží zároveň. Bude zde možnost naskladnění a vyskladnění zboží. Každé naskladnění, vyskladnění a prodej poté bude zohledněn v historii položky. V historii každé položky bude evidováno datum pohybu, počet vyskladněných, naskladněných nebo prodaných kusů a kdo tento úkon provedl. V tomto modulu půjde navíc naskladňovat, vyskladňovat i dotykovým displejem. Aby měl majitel alespoň malý přehled o stavu svého zboží, bude zde vytvořena funkce na 11
kontrolu stavu zboží, které bude barevně odděleno podle počtu zbývajících kusů. Tato funkce nebude nějak zásadní. Bude zde pouze pro orientaci. Seznam zboží by měl jít filtrovat podle kategorie. Mělo by jít i vyhledat zboží pomocí čárového kódu. Tato funkce bude přispívat k rychlejšímu nalezení zboží, které budeme chtít naskladnit,vyskladnit nebo zjistit jeho historii.
2.3 Modul nové směny, prodeje a ukončení směny Asi nejdůležitějším modulem tohoto systému pro zaměstnance bude vytvoření nové směny a následný prodej položek. Bude možné vytvořit pouze jednu aktivní směnu. Jde o malou restauraci, kde pracuje jeden číšník a majitel si sám vaří, proto je logické, že nelze vytvářet více směn najednou. Pokud bude otevřená směna, nebude možné mazat zboží nebo kategorii. Bez vytvoření nové směny, nebude možné prodávat zboží. Prodej zboží zde bude navíc možný i dotykovým displejem. Prodané zboží půjde samozřejmě stornovat. Po skončení směny se zvlášť sečte zboží prodané na baru a zvlášť zboží prodané z kuchyně. Bude se také evidovat zboží, které bylo během prodeje stornováno. Systém bude obsahovat možnost tisku počtu prodaných a stornovaných položek za danou směnu. Ukončit směnu bude moci pouze ten uživatel, který tuto směnu založil nebo samozřejmě majitel.
2.4 Modul zaměstnanci a evidence výplat Zde bude možnost evidence uživatelů. U uživatelů se bude evidovat jméno, příjmení, adresa, telefon, hodinový plat pro pozdější výpočet platu. Majitel zde bude moci nastavit uživatelská práva, login a heslo zaměstnance. Samozřejmě zde bude možnost editace všech těchto údajů. Dále bude mít možnost přesunu zaměstnance mezi neaktivní. To znamená mezi uživatele, kteří nemají právo se do tohoto systému přihlásit. Modul zaměstnanců tedy bude obsahovat seznam aktivních zaměstnanců a neaktivních. Neaktivní zaměstnance bude mít majitel možnost opět přesunout mezi aktivní. Zaměstnanec v tomto modulu bude moci pouze vidět seznam uživatelů. V modulu výplaty zaměstnanci uvidí svůj hodinový plat svojí aktuální hrubou výplatu, nedoplatky a celkovou výplatu. Celková výplata bude aktuální výplata s odečtenými případnými nedoplatky. Přeplatky nebudou brány v potaz. Zaměstnanci zde budou mít i možnost najití historie svých výplat za každý měsíc. Majitel bude mít seznam aktivních zaměstnanců. U každého z nich bude mít přehled o odpracovaných hodinách, hodinovém platu a nedoplatcích. 12
Dále zde bude jak aktuální výplata, tak celková, která se vypočítá po odečtení nedoplatků od aktuální výplaty. Bude zde možnost náhledu do historie výplat.
13
3 Návrh řešení 3.1 Existující známá řešení Při hledání podobných řešení jsem narazil na několik aplikací, které se zabývají provozem restaurace. Některá nalezená řešení měla sice možnosti ovládání z více stanic, ale s více možnými přístupy roste koncová cena aplikace. Bohužel však žádné nalezené řešení není programováno jako internetová aplikace, aby byla možnost přihlášení odkudkoli, což byl základní požadavek zadavatele.
3.2 Použité programovací prostředky Jelikož chce mít zadavatel snadný přístup k tomuto systému odkudkoli, je programovací jazyk použit PHP. Jako značkovací jazyk je zvolen XHTML, některé funkce převážně na kontrolu formulářů jsou psané JavaScriptem. Grafický vzhled je tvořen převážně pomocí kaskádových stylů CSS. Jako zdroj dat je pak použit databázový systém MySQL. Tyto programovací prostředky jsou zvoleny hlavně pro jejich širokou podporu u webhostingů a myslím si, že jsou v dnešní době asi nejpoužívanějšími prostředky pro tvorbu webových aplikací. Druhou variantou bylo programování pomocí skriptovacího prostředí ASP od společnosti Microsoft, ale s tímto programovacím jazykem nemám žádné praktické zkušenosti, proto jsem dal přednost PHP.
3.2.1 MySQL „MySQL je databázový systém, vytvořený švédskou firmou MySQL AB, nyní vlastněný společností Sun Microsystems, dceřinou společností Oracle Corporation.“ [1] Je to jeden z nejznámějších databázových systémů, používaných pro webové aplikace. Sice neobsahuje tolik funkcí jako některá konkurence, ale spojení s phpMyAdmin, PHP a Apache, obsluhu této databáze a programování webových aplikací velice usnadňuje. Při tvorbě tohoto systému byla také použita aplikace phpMyAdmin a webový server Apache. V databázi MySQL se nechají tabulky tvořit několika způsoby, nejzákladnějším typem tabulek je MyISAM. Tento typ však nepodporuje propojení tabulek cizími klíči, které je velice přínosné pro tvorbu databáze. Při tvorbě databázových tabulek pro tento systém je tedy použit typ InnoDB. Tento typ již propojení tabulek přes cizí klíče podporuje. Můžeme tedy vzájemně propojeným tabulkám nastavit chování 14
podřízené tabulky (v případě nového záznamu, změny záznamu nebo smazání záznamu) oproti nadřízené tabulce. Toto chování se nastavuje direktivou ON UPDATE a ON DELETE. Pokud k těmto direktivám vybereme CASCADE nastavíme cizí klíč tak, že se může změnit nebo smazat, podle odkazu daného klíče. Po vybrání RESTRICT se cizí klíč nemůže změnit nebo smazat podle odkazu daného klíče. Pokud nastavíme SET NULL, tak se cizí klíč po změně nebo smazání odkazu nastaví na NULL (pokud tedy podle definice může být NULL).
Obrázek 2 Spojení tabulek kategorie a zboží
Konkrétně zde na obrázku je vidět spojení tabulek zbozi a kategorie. Je pochopitelné, že zboží musí být vždy v nějaké kategorii, což je dáno cizím klíčem kategorie v tabulce zbozi. Při správném nastavení databáze si však musíme položit otázku. Co se stane, pokud budeme chtít smazat nějakou kategorii? Bez dalšího ošetření by se smazaly i veškeré produkty ve smazané kategorii. Nabízí se tedy dvě řešení. Ošetříme tento stav programově. Pokud se bude některá položka nacházet v kategorii, tak ta kategorie smazat nepůjde. Toto řešení je ale dost nepraktické, v rozsáhlejších systémech je většinou takovýchto situací hodně. Mohlo by se tedy stát, že na nějakou zapomeneme a dojde k chybám. Druhá možnost je použít již zmíněné InnoDB tabulky a nastavit u cizího klíče direktivu ON DELETE RESTRICT. Touto direktivou, jak jsem již předeslal, se zamezí smazání nadřazené kategorie. Pokud by však nastal opačný případ, a sice že budeme chtít smazat kategorii se všemi položkami, stačí nastavit ON DELETE CASCADE.
3.2.2 PHP Je skriptovací programovací jazyk, vyvinutý pro programování internetových aplikací a dynamických internetových stránek. Při použití v dynamických stránkách je k uživateli přenášena až výsledná činnost. Samotné skriptování je prováděno na straně serveru. PHP také podporuje mnoho knihoven. Je to asi nejrozšířenější a nejpopulárnější programovací jazyk pro web. Hlavně díky svému jednoduchému použití. Kombinuje vlastnosti několika programovacích 15
jazyků, čímž nechává programátorovi celkem volnou ruku. Poprvé PHP zhlédlo světlo světa v roce 1995, kdy oficiální název zněl: „Personal Home Page Tools (PHP Tools)“. V roce 2001 byly ve verzi 4.1.0 představeny tzv. superglobální proměnné ($_GET, $_SESSION,
$_POST,
$_SERVER). Použití globálních proměnných je stále možné pomocí
konfigurační direktivy register_globals, ale z bezpečnostních důvodů je to silně nedoporučováno. Superglobální proměnou $_SESSION používá PHP pro udržení informací o relaci mezi serverem a uživatelem. Při spuštění $_SESSION vygeneruje identifikátor a pomocí tohoto identifikátoru rozezná koncového uživatele. V tomto systému jsem superglobální proměnou $_SESSION použil v přihlašovacím prostředí pro zjištění aktuálně přihlášené osoby a také pro různá oprávnění. Zatím poslední verze PHP 5.3.5 vyšla letos v lednu. Zároveň se pracuje i na verzi PHP 6.
3.2.3 JavaScript JavaScript je skriptovací jazyk používaný pro programování webových stránek spolu s HTML. Řadí se mezi objektově orientované skriptovací jazyky. Má podobnou syntaxi jako C, C++, nebo Java. S programovacím jazykem Java však nemá nic společného. Tento jazyk se dá použít například na hlídání vkládání správných dat do formulářů. Pro ovládání tlačítka nebo animaci obrázků. V kombinaci s CSS dokáže automaticky měnit grafický vzhled webu a tak dále. Do aplikace nebo webových stránek se dá vkládat třeba v hlavičce HTML kódu mezi tagy <script> a nebo importovat externím souborem s příponou *.js. Oproti PHP se spouští v internetovém prohlížeči přímo u uživatele na počítači. To přináší určitá bezpečnostní rizika a tak JavaScript nemůže třeba pracovat se soubory. Používání JavaScriptu se nechá i vypnout uživatelem v nastavení internetového prohlížeče. „JavaScript je také možno spouštět v operačních systémech Windows pomocí programu Windows Script Host a nahradit tak dávkové soubory MS-DOS.“ [2]
3.2.4 XHTML XHTML (Extensible Hypertext Markup Language), což v překladu znamená rozšířitelný hypertextový značkovací jazyk. Jde o značkovací jazyk pro tvorbu hypertextových dokumentů ve webovém prostředí, vyvinutý W3C (World Wide Web Consorcium). Původně se XHTML měl stát nástupcem jazyka HTML, jehož vývoj byl verzí 4.01 ukončen. V roce 2007 však došlo k založení pracovní skupiny, která má za cíl vytvořit novou verzi HTML, která ponese 16
označení HTML 5 a její XML (Extensible Markup Language) variantu XHTML 5. Vedle toho paralelně pokračuje i vývoj XHTML 2.0. Nově vyvíjená verze XHTML 5 přinese kromě několika nových tagů i možnost tvorby offline aplikací. Jelikož je XHTML v podstatě kombinací HTML a XML, je až na pár výjimek s HTML zpětně kompatibilní. Prvním rozdílem mezi XHTML a HTML je již na začátku v doctype. Zde jsou pro srovnání validní doctype XHTML (1.0 transitional), který je mimochodem použit v této práci a HTML (4 Transitional).
Další větší rozdíly mezi HTML a XHTML jsou u nepárových a párových tagů. V XHTML musí být na rozdíl od HTML všechny tagy ukončeny, a to i nepárové, jako jsou například , <meta>, , nebo . Tyto tagy musíme vždy ukončit zpětným lomítkem. Rozdíl je také v tom, že v XHTML musí být všechny tagy a jejich atributy psány malými písmeny a atributy uzavřeny do uvozovek. Posledním příkladem, který bych uvedl, je zákaz křížení tagů. Zde je pár příkladů pro představu. Chyba – velká písmena, atribut není v uvozovkách a nepárový tag není ukončen Správně – atribut je v uvozovkách a nepárový tag je ukončen ukončovacím lomítkem Chybné kříženíSprávně Existuje několik verzí XHTML. Některé jsou přísnější, některé zase méně a povolují i tagy, které striktní XHTML zakazuje. Můj systém není programován striktním jazykem XHTML. Bývá to občas problém u některých verzí prohlížečů, které to nepodporují. Při psaní kódu jsem však dodržel veškerá pravidla, která jsem zde uvedl.
17
3.2.5 CSS – kaskádové styly CSS neboli Cascading Style Sheets je jazyk používaný na upravení grafického vzhledu internetových stránek a aplikacích napsaných v HTML, XML nebo XHTML. Stejně jako XHTML byl tento jazyk vyvinut standardizační organizací W3C. Smysl kaskádových stylů spočívá ve vytvoření si externího CSS souboru, kde si programátor nadefinuje styly pro různé části stránek nebo přímo pro XHTML tagy. Tyto nadefinované prvky se poté zobrazují v celých stránkách nebo aplikaci přesně tak, jak jsme je nadefinovali a není potřeba poté vzhled definovat v HTML kódu. Pozdější úprava vzhledu aplikace je tedy mnohem jednodušší. Použitím tohoto prostředku by se mělo omezit nastavování vzhledu přímo v HTML kódu a tím tento kód zpřehlednit. Bohužel nevýhodou těchto stylů jsou webové prohlížeče. Ty obsahují v implementaci CSS chyby a je tedy velice obtížné napsat takový kód, který by se zobrazoval stejně alespoň na těch nejpoužívanějších prohlížečích (Internet Explorer, Mozila Firefox, Google Chrome, Opera atd.). Tento problém se však poslední dobou začíná zlepšovat, hlavně opravami chyb v prohlížečích a aktualizací na jejich novější verze. Pro upravení grafického vzhledu tohoto systému jsem použil dva externí CSS soubory, jeden pro nadefinování vzhledu systému design.css a druhý nadefinovaný pro vytisknutí dat design_tisk.css.
3.3 Použité volně dostupné prostředky 3.3.1 Knihovna FPDF Tato knihovna slouží pro vytváření PDF dokumentů v aplikacích programovaných jazykem PHP. Je volně ke stažení na webových stránkách http://www.fpdf.cz/download/, kde jsem si stáhl verzi 1.6 pro PHP5. Používání této knihovny je jak pro komerční, tak pro nekomerční využití zcela zdarma. Stažený soubor obsahuje nejen zdrojové soubory, ale navíc i dokumentaci a ve složce tutoriál jsou veškeré návody na vytvoření PDF stránky přesně podle své představy (vše v Angličtině). V tomto systému je funkce připravena pro budoucí využití. Tímto využitím by měl být do budoucna tisk jídelního lístku v PDF formátu. Pro připojení do systému jsem však musel na stránce http://www.fpdf.fruit-lab.de/ vygenerovat soubory s českými fonty (jeden pro standardní písmo a druhý pro tučné). Knihovna FPDF postrádá české fonty. Tento generátor funguje tak, že po vložení souboru s fontem typ.ttf vytvoří soubory, které jsou potřeba pro 18
knihovnu FPDF. Vygenerované soubory jsem pak nakopíroval do adresáře font, který je v kořenovém adresáři fpdf.
3.3.2 Barcode Generator Program Barcode Generator je určený ke generování čárových kódů na webových aplikacích psaných v jazyce PHP a také ASP.net. Pro nekomerční použití je volně ke stažení na webu http://barcodephp.com/download.php. Tento generátor podporuje standardy čárových kódů ve formátu například: Codabar, Code39, Code93, Code128, EAN-8, EAN-13 atd. Také generuje 2D formáty čárových kódů jako třeba PDF417, Aztec atd. Já jsem tento generátor pro svůj systém využil na vytváření čárových kódů pro položky, které neobsahují etiketu s čárovým kódem, jako jsou třeba točená piva nebo veškerá uvařená jídla. Z nabízených formátů jsem využil pouze Code39. „Code 39 umožňuje kódovat 43 znaků ASCII: velká písmena (A—Z), číslice (0—9), mezeru a speciální znaky (* – $ % . / +). Každý znak je kódován pomocí 9 elementů (5 čar a 4 mezery, z nich jsou vždy 3 široké a 6 úzkých (odtud název 3z9 nebo 3/9 a obvykle jen 39)). Znaky jsou od sebe odděleny úzkou mezerou. Slovo začíná a končí zvláštním znakem (start/stop).“ [3] Na stránce http://www.barcodephp.com/1d/demo/html/code39.php, kde se nachází přímo tento generátor v praxi, jsem si po zadání parametrů na vytvoření čárového kódu vyzkoušel, jak by měl vypadat tisknutelný kód. Zadal jsem potřebný formát výstupu obrázku, rozlišení, výšku a font jakým se má čárový kód zobrazit. Poté jsem pro tyto proměnné vytvořil v souboru functions.php funkci na propojení mého systému se staženým generátorem čárových kódů. if(isset($_GET["barcode"])) { if (IsSet($_GET["barcode"])) { $barcode = $_GET["barcode"]; } if (IsSet($_GET["nazev"])) { $nazev = $_GET["nazev"]; } $code = "code39"; $output = 1; $thickness = 50; $res = 1; $text2display = $barcode; $font_family = "Arial.ttf"; $font_size = 8; $a1 = ''; $a2 = ''; $a3 = ''; 19
echo ' <span class="popis_kodu">'.$nazev.''; }
Všechny tyto proměnné jsou odkazem posílány do souboru image.php, který se nachází ve složce htlm adresáře barcode.
20
4 Popis implementace 4.1 Databáze První moje kroky na realizaci databáze vedly přes návrh ER-diagramu, který jsem navrhl v kreslícím prostředí programu Dia. Toto prostředí jsem si vybral, protože jsme ho používali v předmětu Databázové systémy. K obsluze a správě databázového stroje jsem použil standardní nástroj phpMyAdmin, kde jsem tento návrh také zrealizoval. Tabulky v databázi jsou realizovány typem InnoDB. Typ InnoDB jsem vybral hlavně pro podporu cizích klíčů, ze kterých se pak také jednoduše nechá vygenerovat model dat.
Obrázek 3 Model dat
Tento model dat, který je vidět na obrázku, jsem vygeneroval pomocí programu MySQL Workbench 5.2 CE. V tomto modelu dat se nachází veškeré tabulky, které jsou v dané databázi 21
obsaženy. Jednotlivé řádky v těchto tabulkách jsou barevně odlišeny. Žlutý klíč před atributem značí primární klíč, červený kosočtverec značí cizí klíče a modrý kosočtverec značí obyčejné atributy.
4.2 Vytvořená struktura kořenového adresáře Kořenový adresář systému obsahuje tyto položky: barcode, design, fpdf, pages, index.php, carovy_kod.php,
katalog.php,
kategorie.php,
klavesnice.php,
konec_smeny.php,
novy_zamestnanec.php, objednavka.php, sklad.php, smena.php, vyplata.php. Položky barcode, design, fpdf a pages jsou adresáře obsahující další položky a zbytek jsou soubory.
4.3 Popis jednotlivých položek adresářů Jak jsem již uvedl adresář barcode obsahuje soubory a další adresáře, pro tvorbu čárových kódů (viz kapitola 3.3.2). Pro nekomerční účely je ke stažení zdarma. Pokud by se však chtěl tento systém v budoucnu použít pro komerční účely, musela by být zakoupena licence. Adresář design, jak už název napovídá, obsahuje dva CSS soubory a všechny ikony, které jsou použity v systému. První soubor design_tisk.css obsahuje nadefinované styly pro grafický vzhled při tisku dokumentu a druhý soubor design.css definuje grafický vzhled systému.
Obrázek 4 Ukázka grafického řešení systému
Na obrázku vidíme grafický vzhled systému. Jedná se o neveřejný systém, který bude používat omezené množství lidí. Z tohoto důvodu není použita grafika poutavá, ale je použit grafický vzhled, od kterého se očekává co největší přehlednost. Tabulka vypisovaných hodnot je orámovaná. Menu je zvýrazněno a rohy jsou zakulacené. Zakulacené rohy však nezobrazí staré verze prohlížeče Internet Explorer. S tímto problémem není počítáno, na funkci systému to nemá 22
žádný vliv a systém se bude používat převážně na nových verzích prohlížečů. Hlavně v prohlížečích Google Chrome a Mozila Firefox. Starší verze těchto prohlížečů tyto rohy podporují. Obsah adresáře fpdf obsahuje funkci na tisk PDF dokumentů (viz kapitola 3.3.1). Jde o open source projekt, který je volně ke stažení jako freeware. Výhoda je, že jak soukromé, tak i komerční použití tohoto open source projektu je zcela bezplatné. Do budoucna by se tento systém mohl rozrůst o možnost tvorby a tisku jídelního lístku, proto je tato knihovna připojena. Asi nejdůležitějším adresářem je pages, který obsahuje většinu řídících funkcí. Obsahuje soubor config.php, přes který se tento systém připojuje k databázi. Pro převod do kódování UTF-8 zde bylo použito volání mysql_query("SET CHARACTER SET 'utf8'");. Adresář pages dále obsahuje soubor header.php. Zde je obsah běžné hlavičky HTML dokumentu s několika metatagy pro upravení kódování a import stylovacích souborů CSS a funkcí JavaScriptu. Do header.php je také zařazen script na ověření přihlášeného uživatele. Jsou zde i veškeré JavaScriptové funkce použité při programování a samozřejmě i samotné tělo dokumentu, obsahující rozvržení stránky pomocí oddílů
. JavaScriptové funkce jsou zde převážně pro kontrolu prázdnosti formulářů. Hlídají, aby uživatel nezapomněl vyplnit veškerá pole formuláře. Zde pro příklad funkce, která hlídá vyplnění názvu zboží. Pokud uživatel název nevyplní, formulář se neodešle a systém ho vyhodnotí jako chybný. function kontrola_empty(formular) { var nazev = formular.nazev.value; if(nazev != "") { var je_ok = 1; } else { var je_ok = false; } if (je_ok == false) alert('Musíte zadat název zboží!'); return je_ok; }
Výhoda používání JavaScriptových kontrol je, že se provedou před odesláním formuláře na server. Pokud špatně vyplním formulář a odešlu ho, systém vrátí chybu. Formulář však zůstane vyplněný stejně jako před odesláním. Stačí pak tedy dopsat pouze chybějící údaj a formulář odeslat. Pokud bychom kontrolu formulářů řešili PHP funkcí, museli bychom špatně vyplněný formulář vyplňovat celý znova. 23
Skript na přihlášení uživatele zkontroluje, zdali se zadané heslo shoduje s heslem, který má tento uživatel uložené v databázi a pokud se shodují, uloží se zadaný login i heslo do $_SESSION. if($heslo_db == $heslo_fr) { $_SESSION["login"] = $login; $_SESSION["heslo"] = $heslo_db; }
Globální pole $_SESSION[“login”] je poté v tomto systému použito při různých MySQL dotazech, například pro zjištění aktuálně přihlášeného zaměstnance, nebo při různých podmínkách a oprávnění. Zdali je uživatel stále přihlášen zjišťuje podmínka, kterou obsahuje každý spustitelný soubor. if(isset($_SESSION["heslo"]) && ($_SESSION["heslo"] == $heslo_db) ):
Pokud tato podmínka není splněna, uživatel musí opět vyplnit přihlašovací formulář. else: echo '
'; endif;
Dalším souborem obsaženým v adresáři pages je soubor functions.php. Tento soubor obsahuje nadefinované globální proměnné, které se pak používají při programování. V tomto souboru je i několik globálních funkcí, jako například funkce pro zápis data a času. function datum_cas_z_sql($sql_datum) { $cas = substr($sql_datum,11,8); $datum = substr($sql_datum,0,10); $a = explode(':',$cas); $b = explode('-',$datum); 24
Tělo této funkce tvoří další PHP funkce na rozdělení explode(string separator, string, limit) a naopak zase na sloučení data a času implode(string glue, array pieces) a funkce substr(), která má parametry start a length. Parametr start určuje, odkud se začíná prvek brát a length je velikost braného prvku. Další použitá globální funkce slouží na převod řetězců str_replace(), kterou jsem použil v modulu evidence výplat (viz kapitola 4.4.7) pro zobrazení aktuálního měsíce. Soubor function.php je hlavně používán pro zachycení vstupů všech formulářů, ve kterých se ukládají, editují nebo mažou prvky z databáze. Zde pro ukázku funkce na uložení nové položky. if(isset($_POST["new_zbozi"])) { if (IsSet($_POST["nazev"])) { $nazev = $_POST["nazev"]; } if (IsSet($_POST["ean"])) { $ean = $_POST["ean"]; } if (IsSet($_POST["cena"])) { $cena = $_POST["cena"]; } if (IsSet($_POST["kat"])) { $kat = $_POST["kat"]; } if(!$db = MySQL_Query("INSERT INTO zbozi (nazev, ean, cena, kategorie) VALUES ('{$nazev}','{$ean}','{$cena}','{$kat}')")) { echo '
Tento EAN je již v databázi, neuloženo!
'; } else { echo '
Vloženo do katalogu: '.$nazev.'
'; }}
Pokud je nastaveno new_zbozi, potvrzením a odesláním formuláře a dojde i k nastavení ostatních položek vyplněných ve formuláři. Uloží se pomocí SQL dotazu nové zboží do databáze. Pokud již existuje stejný ean (primární klíč) v databázi jako právě vkládaný nebo nastala jiná chyba, zboží se neuloží a systém vyhodnotí chybu. Takto vypadá formulář k předchozí funkci.
Do tohoto formuláře je vložen while cyklus, který s pomocí tagu <select> vypíše do roletky veškeré názvy kategorií pro snadný výběr kategorie. Tímto je ošetřeno vytvoření zboží s neexistující kategorií. Před tímto formulářem musíme samozřejmě vytvořit proměnnou $kategorie, do které uložíme tento SQL dotaz. $kategorie = mysql_query("SELECT nazev FROM kategorie");
Nevyplnění položky formuláře je ošetřeno JavaScriptem. function kontrola_zbozi() { var nazev = self.document.forms.zbozi.nazev.value; var cena = self.document.forms.zbozi.cena.value; var ean = self.document.forms.zbozi.ean.value; if(nazev != "" && cena != "" && ean != "") { var je_ok = 1; } else { var je_ok = false; } if (je_ok == false) alert('Musíte vyplnit všechna pole!'); return je_ok; }
Zde je funkce pro kontrolu vložení názvu, ceny a eanu (čárového kódu). Pokud zůstane jedno z těchto políček nevyplněné, JavaScript zabrání odeslání formuláře a zahlásí chybu. Podobným způsobem jsou v tomto systému řešeny veškeré formuláře, jako jsou: přidání nového zaměstnance, editace zaměstnance, přesun zaměstnance do historie a zpět, uložení nové kategorie, editace názvu kategorie, smazání kategorie, uložení nového zboží, editace ceny a názvu zboží, vyskladnění a naskladnění zboží, uložení nového prodeje, smazání prodeje, uložení výplat, vytvoření nové směny a nakonec ukončení směny. Posledním souborem v adresáři pages je footer.php. Tento soubor plní funkci tzv. patičky, ukončuje tedy dokument. Navíc tento soubor obsahuje programový kód funkce klávesnice. Tato 26
funkce je příprava pro budoucí připojení dotykového displeje. Dá se však velice jednoduše použít již teď pro obsluhu systému. Například pro prodej nebo naskladnění a vyskladnění zboží.
Obrázek 5 Použití funkce klávesnice v modulu historie zboží
Funkce klávesnice je vytvořena pro ovládání modulu sklad a prodej zboží. Je tvořena jednoduchým menu, ve kterém jsou pomocí SQL dotazu zobrazeny všechny kategorie vycentrované na střed. V pravém rohu se nachází storno a zavřít. Odkazem zavřít je klávesnice zavřena. Pokud klikneme na storno, provedeme událost onclick, která pole „EAN“ vynuluje a pole „Počet“ nastaví na jedna. onclick="self.document.forms.prodej.ean.value = null; self.document.forms.prodej.pocet.value = 1;
Každá kategorie v zobrazeném menu funguje jako odkaz pro zobrazení veškerého zboží v dané kategorii. Po zvolení názvu zboží se vyplní čárový kód tohoto zboží do příslušného pole (na obrázku EAN:). Obrázek lupy je v této funkci speciálně pro modul historie zboží. A slouží pro hledání čárového kódu vybraného zboží, kterým vyplníme pole „Hledat EAN:“. Pro okamžité vyplnění okna EAN je zde užit následující skript. <script> document.getElementById('ean').focus(); ";
27
Tento skript zajišťuje umístění kurzoru do pole „EAN“ ihned po načtení stránky. Tento způsob šetří jedno kliknutí myší při vkládání čárového kódu. Do budoucna tím bude i jednodušší ovládání dotykového displeje. Pro vyplnění tohoto pole pomocí klávesnice slouží následující funkce. function zbozi(ean, idx) { if(self.document.forms.prodej.ean.value == ean) { var pocet = self.document.forms.prodej.pocet.value; pocet++; self.document.forms.prodej.pocet.value = pocet; } self.document.forms.prodej.ean.value = ean; document.getElementById(idx).style.color = 'red'; setTimeout(function() { document.getElementById(idx).style.color = 'black'; }, 500); }
Po kliknutí na tlačítko zboží se pomocí události onclick vyvolá funkce zbozi, které se předají dva parametry. Parametr ean je skutečný čárový kód zvoleného zboží a parametr idx slouží k rozlišení tlačítka, které vyvolalo událost onclick. Pokud je již v poli EAN vyplněn shodný čárový kód, jaký vyvolal tuto událost, zvýší se hodnota pole Počet o jedna. V praxi to znamená, že uživatel kliknul na tlačítko stejného zboží dvakrát nebo vícekrát za sebou. Následuje nastavení hodnoty čárového kódu do pole EAN a zabarvení tlačítka s id rovným předané proměnné idx na červenou barvu. Nastavením parametrů pro funkci setTimeout se spustí časovač na 500 milisekund a po uplynutí této doby se barva tlačítka s id rovným předané proměnné idx vrátí zpět na černou. function zbozi_search(ean, idx) { self.document.forms.search.ean_search.value = ean; document.getElementById(idx).style.color = 'blue'; setTimeout(function() { document.getElementById(idx).style.color = 'black'; }, 500); }
Zde zobrazená funkce zbozi_search funguje na stejném principu jako již zmíněná funkce zbozi. Jediný rozdíl je, že název zboží po kliknutí zmodrá a nevyužívá se vícenásobného kliknutí. Tato funkce je využívaná pouze v modulu sklad. 28
4.4 Jednotlivé moduly
Obrázek 6 Rozdělení jednotlivých modulů a oprávnění pro zaměstnance
Jak je zřejmé z obrázku, číšník, jakožto zaměstnanec má práva omezená a nemůže tedy pochopitelně využívat veškeré funkce, které systém nabízí. Hlavně nemá právo mazat nebo editovat položky. Jeho hlavní pracovní náplní je prodej položek. Tento prodej se odehrává po založení nové směny v modulu prodej položek.
29
Obrázek 7 Rozdělení jednotlivých modulů a oprávnění pro majitele
Pro rychlý přehled jsou na obrázku znázorněny veškeré moduly a jejich funkce. Majitel jakožto i správce systému má veškerá práva a může využívat veškeré funkce, které systém nabízí. Pro detailnější přehled a popis bude každý modul popsán zvlášť.
4.4.1 Kategorie Převážná část tohoto modulu je programována v souboru kategorie.php. V tomto modulu je možné vytvořit novou kategorii a té přiřadit jakého je typu. Majitel restaurace pak má navíc oprávnění jakoukoli kategorii editovat a smazat. Kontrola vyplnění formuláře probíhá JavaScriptovou funkcí, kterou obsahuje soubor header.php. Uložení do databáze pak zajišťuje 30
obyčejný MySQL dotaz, tento krok se provádí v souboru functions.php. Jak jsem již uvedl, veškeré formuláře jsou kontrolovány a hodnoty z nich ukládány podobným způsobem již popsaným (viz kapitola 4.3). Výpis dat do tabulky pro zobrazení, je řešen vytvořením proměnné kategorie, která provede SQL dotaz. Pro ukázku: $kategorie = mysql_query("SELECT * FROM kategorie");. Dále je vytvořena proměnná položka a pomocí cyklu while se vypisuje pole hodnot načtené proměnné kategorie. Pro ukázku: while ($polozka = MySQL_Fetch_Array($kategorie)). Dokud pole hodnot obsahuje nějaké položky, jsou tyto hodnoty vypisovány do připraveného formuláře. Tímto nebo velice podobným způsobem jsou v tomto systému řešeny veškeré výpisy dat z databáze.
4.4.2 Zboží V Katalogu zboží, jak název napovídá, je uložen veškerý sortiment zboží, které restaurace nabízí. Tento modul obsahuje soubor katalog.php. Zaměstnanci zde mohou přidávat nové druhy zboží rozdělené do kategorií. Majitel pak může editovat název, cenu a mazat položku pokud již nebyla někdy prodána. Tento modul obsahuje i funkci pro vyhledávání pomocí čárového kódu nebo pomocí kategorií. Stejnou funkci obsahuje i modul historie zboží, funkci tedy popíši pouze zde. if (IsSet($_GET["ean_search"])) { $ean_search = $_GET["ean_search"]; } else $ean_search = ""; if (IsSet($_GET["kategorie_search"])) { $kategorie_search = $_GET["kategorie_search"]; } else $kategorie_search = ""; if (IsSet($_GET["filtr"])) { $filtr = $_GET["filtr"]; } else $filtr = ""; $db_search = ""; if($filtr=="Vyhledat") { if($ean_search!="") { $db_search = "AND zbozi.ean = '{$ean_search}'"; } else { $db_search = "AND kategorie.id_kategorie = '{$kategorie_search}'"; }}
Po odeslání formuláře s názvem prvku ean_search, kategorie_search a filtr tedy po jejich nastavení. Uložíme do proměnné $db_search „část SQL dotazu“, podle toho, zdali 31
vyhledáváme podle čárového kódu nebo podle kategorie. Tuto proměnnou poté vložíme do SQL dotazu, kterým se vypisují potřebná data z databáze. Vložíme tuto proměnnou na místo, kam bychom napsali tu část SQL dotazu, kterou jsme uložili do proměnné $db_search. Tímto krokem v podstatě ušetříme jeden SQL dotaz. Speciální funkcí zde, je tisk čárových kódů vybraného zboží, popsané v kapitole Barcode Generator (viz kapitola 3.3.2).
4.4.3 Historie zboží V systému je tento modul nazván jako sklad. Jsou tu funkce na naskladnění a vyskladnění zboží. Vyskladněním je vyřešen problém s položkami, kterým projde doba spotřeby, a nedají se tedy prodat. Tyto funkce jsou řešeny jednoduchým formulářem. Po provedení tohoto úkonu se do řádku kdo v tabulce sklad uloží jméno a příjmení přihlášeného zaměstnance.
Obrázek 8 Okno historie zboží
Jak vidíme na obrázku, vloží se ještě před jméno vykonaný úkon, pokud se zboží vyskladní, uloží se do historie tohoto zboží: „Vyskladnil jméno a příjmení“, když se zboží naskladní tak je to: „Naskladnil jméno a příjmení“ a pokud se prodá zboží, uloží se: „Směna jméno a příjmení“. Tato historie se zobrazí po kliknutí na název zboží. Z tohoto názvu je programově udělán odkaz na zobrazení okna s historií. Tedy po kliknutí na tento odkaz se zobrazí historie za tento měsíc, ale je tu i možnost zobrazení celé historie zboží.
32
4.4.4 Založení nové směny a prodej položek Tento modul je obsažen v souboru smena.php. Celý tento modul slouží převážně pro založení nové směny. Tento krok je řešen jednoduchým formulářem. Do databáze se uloží jméno číšníka a čas kdy tuto směnu založil.
Obrázek 9 Založení nové směny
Na obrázku je vidět, jak vypadá rozhraní pro založení nové směny a také část tabulky s historií vytvořených směn. Zde bych rád upozornil, že čas a datum zde zobrazovaný je pouze orientační. Do databáze se ukládá čas reálný, pomocí MySQL funkce NOW(). Pokud by se ukládal čas zde zobrazovaný mohla by nastat chyba. Kdyby číšník nepotvrdil tlačítko „Nová směna“ hned, ale až po nějaké době, uložil by se do databáze nesprávný datum. Po založení směny je číšník přesměrován do modulu prodej položek. Tento modul by měl být pro číšníka stěžejní. Přes jednoduchý formulář se zde prodává zboží. Vložením čárového kódu do pole s názvem „Vložte čárový kód“ a potvrzením tlačítka „Potvrdit“, prodáme požadované zboží. Vložit čárový kód lze ručním vypsáním čárového kódu, pomocí čtečky čárových kódu a pomocí již popisované funkce klávesnice. Jde opět vkládat několik kusů najednou. Po prodeji jsou položky po jedné zobrazovány do tabulky. Vypisování do tabulky prodeje po jednom kuse je kvůli případnému jednoduchému stornování prodeje. Storno položky provedeme kliknutím na křížek s titulkem smazat, který je u každé položky. Pokud jeden číšník otevře směnu, nemá právo nikdo jiný otevřít novou směnu nebo prodávat. Tímto oprávněním je zamezeno prodeji položek cizím číšníkem. Mohla by totiž lehce nastat situace, díky možnému přístupu k systému z více míst, že jeden číšník založí směnu a druhý číšník mu v ní bude prodávat zboží, což je nepřípustné. Systém má ošetřené odhlášení číšníka ze systému, pokud má číšník otevřenou směnu, nemá možnost se odhlásit. Musí tedy nejprve směnu ukončit a až poté se může odhlásit.
33
4.4.5 Konec směny Na konci každé směny je číšník povinen vyplnit pole „Peněženka“. Zde vloží číslo, které odpovídá hodnotě peněz, které za danou směnu vyinkasoval. Poté potvrzením tlačítka „Ukončit směnu“, ukončí svojí směnu. Nejdůležitější je rozdělení na zboží prodané z baru a zboží prodaného z kuchyně. Tento krok je řešen pomocí SQL dotazů. Pro názorný příklad, jeden SQL dotaz použitý pro získání hodnoty zboží prodaného na baru. $bar = MySQL_Fetch_Array(mysql_query("SELECT SUM(zbozi.cena) AS cena FROM prodej, zbozi, kategorie WHERE prodej.zbozi = zbozi.ean AND prodej.stav='ok' AND zbozi.kategorie = kategorie.id_kategorie AND kategorie.typ = 'Bar' "));
Do proměnné $bar se uloží celková cena pole prvků z tabulky prodej, které mají stav roven ok (pokud by byl stav roven zruseno, jedná se o zboží, které bylo během prodeje stornováno) a typ kategorie je bar. Stejným způsobem je řešen prodej z kuchyně. Obdobně je řešen i výpis prodaných kusů jednotlivého zboží.
Obrázek 10 Ukončení směny
Na obrázku vidíme příklad ukončení směny. Vypisujeme jméno a příjmení číšníka, v jaký čas pracoval, peníze, které vložil do pole „Peněženka“ a pak zvlášť tržbu na baru a v kuchyni. Dále je 34
do tabulek vypsáno jednotlivé zboží rozdělené podle baru a kuchyně a nakonec stornované zboží. Výpis stornovaného zboží je řešen obdobně, jako prodaného jen má v tabulce prodej, atribut stav roven zruseno. Veškeré tyto vypsané věci jsou zároveň ukládány do tabulky sklad pro pozdější případnou kontrolu a historii zboží. Tento list ukončení směny zobrazený na obrázku (viz Obrázek 10 Ukončení směny) je možné vytisknout.
4.4.6 Zaměstnanci Modul
zaměstnanci
slouží
převážně
pro
majitele
tohoto
systému.
Drží
informace
o zaměstnancích, ale i majiteli samotném. Majitel zde může přidávat zaměstnance. U zaměstnanců se eviduje jméno, příjmení, adresa, telefon a hodinový plat pro pozdější výpočet platu. Majitel při přidávání zaměstnance navíc ještě nastaví uživatelská práva, login a heslo tohoto zaměstnance. Pokud majitel zaměstnanci nastaví atribut pristup na ano má stejná oprávnění přístupu jako on. Možnost editace uživatelů probíhá v podstatě ve stejném formuláři jako vložení nového uživatele. Pozor jsem si při programování musel dát pouze na editaci loginu a hesla, musí se do databáze uložit pod jinou proměnnou, než pod jakou je bráno z databáze, aby nedošlo k přepsání globální proměnné $_SESSION a tím i změně aktuálně přihlášeného uživatele. Uživatelé nejdou smazat, jdou pouze přesunout mezi neaktivní zaměstnance. Neaktivní zaměstnanec nemá právo se přihlásit do systému, ale majitel má možnost dohledat historii jeho prodejů. Systém samozřejmě nabízí možnost vrácení zaměstnance mezi aktivní zaměstnance. Pro zaměstnance tento modul nabízí pouze přehled jejich spolupracovníků.
4.4.7 Evidence výplat Modul evidence výplat zaměstnancům eviduje a zobrazuje výplaty a jejich historii. Při vstupu sem má zaměstnanec přehled o počtu odpracovaných hodin v aktuálním měsíci, dále vidí svůj hodinový plat, pokud měl v aktuálním měsíci nějaké nedoplatky, tak je zde také uvidí a poslední položkou je celková výplata za tento měsíc. Zaměstnanec si zde může prohlédnout své výplaty i zpětně, stačí jen si v roletce vybrat měsíc, za který chce zobrazit vyplacenou částku. Výběr měsíce v roletce je vyřešen pomocí funkce mesic v souboru function.php.
V proměnné $search je uloženo pole čísel (čísla měsíců) a v proměnné $replace pole řetězců (názvy měsíců). PHP příkaz str_replace nahradí prvek z proměnné $search prvkem z proměnné $replace. Po té již stačí připojit jednoduchý for cyklus a ve spojení s HTML tagem <select> je rozbalovací nabídka měsíců na světě. Tato funkce je použita i pro zobrazení aktuálního měsíce. Zde musíme k této funkci přidat ještě datum ($aktualni_mesic =
date("Y-m",time());), ze kterého vezmeme dva prvky od pátého prvku
(mesic(substr($aktualni_mesic,5,2))). Konkrétně číslo měsíce, které se pak převede na název aktuálního měsíce. Zde na obrázku vidíme vedle příjmení „Odpracováno za měsíc:“ a poté je vložen název tohoto aktuálního měsíce.
Obrázek 11 Modul evidence výplat
Na obrázku vidíme rozhraní pro majitele, pokud zaměstnanec dostane výplatu, majitel klikne na tlačítko „Vyplaceno“, které se u tohoto zaměstnance nachází. Tímto se uloží do databáze vyplacená částka, datum vyplacení a odpracované hodiny vyplaceného zaměstnance. Pokud se takto stane, má zaměstnanec po přihlášení do systému možnost vidět, popřípadě zpětně dohledat svůj příjem. Majitel má také možnost po vybrání měsíce zpětně shlédnout výplaty svých zaměstnanců. Pokud má zaměstnanec zrovna založenou směnu, není mu počítána do aktuální pracovní doby, kterou tedy vidí pouze majitel. Je zde možnost tisku tohoto aktuálního listu. 36
5 Výsledky testování Testování systému zprvu probíhalo pouze na lokálním serveru vytvořeném programem Apache, který je součástí volně stažitelného balíčku EasyPHP, staženého ze serveru http://www.stahuj.cz. Tento balíček navíc obsahuje phpMyAdmin a MySQL pro snadné využívání databáze na operačním systému Windows. Veškeré testování na lokálním serveru probíhalo téměř bez problémů. Každá nově vytvořená funkce byla hned otestována a popřípadě opravena. Po každém větším kroku, vlastně po naprogramování každého modulu, probíhaly konzultace se zadavatelem. Modul jsem buď předělal podle jeho přání, nebo pokračoval dalším modulem. Asi největší problémy
nastali
po
nahrání
již
téměř
hotového
systému
na
web
http://www.hospoda.dsagency.cz. Hosting tohoto webu zastřešuje firma Seonet Multimedia s.r.o. Malý problém představovalo kódování informací braných z databáze, to jsem však vzápětí vyřešil přidáním direktivy mysql_query("SET
CHARACTER
SET
'utf8'"),
kterou se
nastavuje kódování databáze. Tento příkaz jsem umístil do souboru config.php za blok kódu, který obstarává připojení k databázi. Touto jednoduchou direktivou se celý problém vyřešil. Větší problémy však nastaly při spuštění tohoto systému v prohlížeči Google chrome. V tomto
prohlížeči
mně
při
přihlášení
do
systému
vyskočila
tato chyba: Warning:session_start()[function.session_start]:open(/var /lib/php5/sess_6cc8e4aae26f7993d6f1dbb84d0be76a, O_RDWR). Po celkem dlouhém bádání a hledání chyby jsem na internetu narazil na webovou stránku http://www.gallery.menalto.com/node/59927, kde jsem se dočetl, že chyba není na mé straně, ale v nastavení serveru, který není správně nakonfigurován a nemůže se zapisovat do session.save_path nebo nemám oprávnění pro zápis do složky var/lib/php5. Požádal jsem tedy technickou podporu tohoto serveru o nápravu chyby a musím podotknout, že i když má žádost přišla okolo dvacáté hodiny večer, jejich reakce byla opravdu rychlá a chybu během chvíle odstranili.
Po
odstranění
této
chyby
je
nyní
systém
umístěn
na
serveru
http://www.hospoda.dsagency.cz a připraven na zavedení do provozu.
37
6 Srovnání s již hotovými řešeními 6.1 Poznatky z praxe Bohužel musím říci, že z praxe nemám žádnou zkušenost s používáním nebo testováním nějakého softwaru pro řízení nebo obsluhu restaurace, či podobného zařízení. Proto jsem zavítal na internet a zkoušel jsem najít nějaké vyhovující řešení.
6.2 Poznatky z internetu Při hledání podobných řešení jsem na internetu narazil na různé programy zabývající se provozem restaurací a různých jiných podobných zařízení. Našel jsem program Jazz Restaurant, který je však naprogramován jako nadstavba ekonomického programu Pohoda a bez tohoto programu nefunguje. Tento program obsahuje daleko více možností než mnou vytvořený systém, ale tyto funkce by zadavatel zdaleka nevyužil a aby tento systém fungoval, musí se přikoupit licence pro ekonomický systém Pohoda Jazz. Tato realizace je tedy dosti finančně náročná. Jako další možnost pro obsluhu restaurace jsem našel Ekonomický systém Trell od společnosti Trellsoft. Tento systém se mi při čtení dokumentace celkem líbil. Nechá se použít jak pro provoz restaurace, tak třeba benzínové pumpy nebo zlatnictví. Po nainstalování jeho volně stažitelné demoverze, jsem však byl zděšen. Rozhraní tohoto systému obsahuje tak obrovské množství tlačítek a funkcí, že jsem se v tomto systému okamžitě ztratil. U každého z těchto programů se cena odvíjí od počtu licencí. A žádný z možných řešení neposkytuje zadavateli jeho základní požadavek, což je přístup k systému odkudkoli.
38
7 Závěr 7.1 Splnění cílů Hlavním cílem této práce bylo vytvořit jednoduchý a přehledný systém provozu restaurace, který bude majiteli poskytovat informace o vedení skladu, kde majitel uvidí aktuální stav zboží, jeho historii, kdo a kdy jakou položkou prodal či naskladnil. Možnost vytvoření a tisku jídelního lístku a v neposlední řadě také informace o odpracovaných hodinách zaměstnanců. Nakonec jsem do systému nezařadil funkci pro smazání zaměstnanců. Místo této funkce jsem přidal funkci pro přesun zaměstnance mezi neaktivní a zase zpátky, mezi aktivní zaměstnance. Tento krok jsem provedl hlavně kvůli evidenci výplat. Systém měl být umístěn na serveru hospoda.stonecity.cz, ale během vývoje si toto umístění zadavatel rozmyslel kvůli nedostatku místa, a tak je systém umístěn na serveru http://www.hospoda.dsagency.cz. Ostatní hlavní cíle se mi s malými, ale již odstraněnými problémy podařilo splnit. Šifrování hesla algoritmem MD5 v přihlašovacím rozhraní, jsem ještě rozšířil o zašifrování pomoci hash funkce SHA1. Pro tento systém to nemá nejspíš nějaký převratný význam, ale v dnešní době není bezpečnost na internetu ničím zaručena. Připojení čtečky čárových kódů proběhlo bez problémů, jen je potřeba přepnout na anglickou klávesnici. Dokumentace ke čtečce je přiložena v příloze A. Vytvoření funkce tvorby a tisku se nakonec podařila také v pořádku připojit. K tomuto kroku mi dopomohla knihovna Barcode, kterou jsem připojil k mé práci (viz kapitola 3.3.2)
7.2 Problémy a jejich řešení Menší problém představovala optimalizace pro různé prohlížeče (Mozila Firefox, Internet Explorer, Google Chrome a Opera) a s tím i grafický vzhled systému. Jelikož tento systém budou používat převážně laici v oboru IT technologií, snažil jsem se systém udělat co nejpřehlednější a uživatelsky co nejvíce přístupný a myslím si, že se mi to nakonec podařilo. Tento grafický vzhled se dá samozřejmě jednoduše změnit přepsáním kaskádových stylů. Dalším problémem byla práva uživatelů. Zadavatel požadoval, jak jsem již předeslal v úvodu, že zaměstnanci mohou pouze prodávat, nikoliv přidávat či vytvářet položky. Tento požadavek si ale zadavatel při prvních testech programu rozmyslel, a tak jsem musel program poupravit. Nyní již mají zaměstnanci možnost naskladnění či vytváření položek. Malý problém nastal i s prodejem jídel 39
z kuchyně, kde se nespotřebují vždy všechny položky a tak jsem musel vytvořit ještě další funkci na vyskladnění. Problém s umístěním na webu jsem již popisoval (viz kapitola 5).
7.3 Možnosti rozšíření mé práce Možností na rozšíření této práce se nabízí hned několik. Dobrým krokem pro rozšíření tohoto systému by ještě bylo připojit funkci na tvorbu a tisk jídelního lístku. Pro tuto funkci je zde již připravena knihovna FPDF. Do budoucna plánuje zadavatel nákup dotykového displeje, čímž by se obsluha tohoto systému ještě zjednodušila a zrychlila. Pro toto rozšíření je již připravená funkce pojmenovaná jako klávesnice, kterou jsem již popisoval (viz kapitola 4.3). Také by bylo dobré propojit tento systém s internetovými stránkami. Určitě by se tento systém nechal propojit s nějakým jednoduchým pokladním systémem, ale o tyto nadstavby majitel zatím nejeví zájem.
40
Seznam použité literatury [1] Mysql. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, [cit. 2011-05-31]. Dostupné z WWW: .
[2] JavaScript. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, [cit. 2011-05-31]. Dostupné z WWW: .
[3] Čárový kód Codabar. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation,
[cit.
2011-05-31].
Dostupné
z
WWW:
.
Barcode Generator for PHP - Download [online]. 2010, 2011 [cit. 2011-06-08]. Barcode Generator. Dostupné z WWW: .
Diskuse.jakpsatweb.cz [online]. 24.4.2010 [cit. 2011-05-31]. Chyba v príklade časovania. Dostupné z WWW: .
FPdf: jak na české znaky - Zaachi.com [online]. 2008 [cit. 2011-05-31]. FPdf: jak na české znaky. Dostupné z WWW: . Message-Digest algorithm. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, [cit. 2011-05-31]. Dostupné z WWW: .
MySQL - Cizi klice a integ.omezeni typu ON DELETE - stav ? [online]. 6.10.2008 [cit. 2011-05-31]. MySQL -
Cizi
klice
a
integ.omezeni
typu
ON
DELETE
-
stav
?.
Dostupné
z
WWW:
. XHTML. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, [cit. 2011-05-31]. Dostupné z WWW: .
41
Seznam obrázků Obrázek 1 ER - diagram ................................................................................................................... 9 Obrázek 2 Spojení tabulek kategorie a zboží ................................................................................. 15 Obrázek 3 Model dat ...................................................................................................................... 21 Obrázek 4 Ukázka grafického řešení systému ............................................................................... 22 Obrázek 5 Použití funkce klávesnice v modulu historie zboží ...................................................... 27 Obrázek 6 Rozdělení jednotlivých modulů a oprávnění pro zaměstnance .................................... 29 Obrázek 7 Rozdělení jednotlivých modulů a oprávnění pro majitele ............................................ 30 Obrázek 8 Okno historie zboží ....................................................................................................... 32 Obrázek 9 Založení nové směny .................................................................................................... 33 Obrázek 10 Ukončení směny ......................................................................................................... 34 Obrázek 11 Modul evidence výplat ............................................................................................... 36
42
Seznam použitých zkratek •
PHP - Personal Home Page
•
HTML - HyperText Markup Language
•
XHTML - eXtensible HyperText Markup Language
•
XML - Extensible Markup Language
•
MySQL - databázový systém
•
JavaScript - objektově orientovaný skriptovací jazyk
•
CSS - Cascading Style Sheets (Kaskádové styly)
•
WWW - World Wide Web
•
W3C - World Wide Web Consortium
•
PDF – Portable Document Format
43
Slovník pojmů •
HTML tagy – Klíčové značky, pomocí nichž se utváří HTML kód, který internetový prohlížeč interpretuje do vizuální podoby.
•
ER-diagram – Model používaný pro abstraktní a konceptuální znázornění dat.
•
Primární klíč – Jde o jednoznačný identifikátor databázové tabulky.
•
Cizí klíč – Slouží k propojení 2 tabulek ve vztahu 1:N. Sloupec s cizím klíčem je v tabulce na straně N a rozvíjí díky němu informace v této tabulce.
•
Webová aplikace – Program realizovaný pomocí technologií používaných na internetu a zároveň k němu lze z internetu přistupovat.
•
SQL dotaz – Je dotaz, který vytvoříme pomocí příkazu SQL a získáme jejím použitím informace z databáze
•
Doctype – Je to tak zvaná deklarace dokumentu.
44
Seznam příloh A. Datasheet použité čtečky čárových kódů. B. CD se zdrojovými kódy systému a uživatelskou příručkou na používání čtečky čárových kódů (v češtině).