Schvalovací postupy (příklad - spisová služba) |
Top Previous Next |
Seznam témat: Tento příklad je určen administrátorům systému. Zadání: Mějme standardní „dodavatelskou smlouvu“. Chceme zajistit, aby dokument pořízený do systému někdo dostal na starost, někdo jiný jej zkontroluje (přezkoume), odpovědná osoba jej podepíše a pak bude označen jako platný. Chceme, aby po přezkoumání už nebylo možno dokument změnit. Dále chceme, aby každý uživatel stále viděl přehled dokumentů, se kterými má zpracovat.
Schvalovací postup vytvořte pomocí funkce schvalovací postupy (procesy). Přidejte nový postup (definujte kód postupu a jeho název): Formulář pro zadání schvalovacího postupu
Nyní si promyslete kroky, které povedou k vyřízení smlouvy a též stavy dokumentu. Úvaha by měla být taková, že dokument je na začátku v nějakém výchozím stavu a nějaký pracovník má úkol spojený s tímto dokumentem (Smlouva je rozpracovaná a pracovník A má úkol smlouvu připravit). Jakmile pracovník dokončí svůj úkol, dokument získá nový stav a je předán jinému pracovníkovi. Takto projde celý proces po svůj poslední krok. Příklad nastavení
Podle výše uvedené tabulky nastavte schvalovací postup. Postup s dobou provedení Nyní vytvořte číselnou řadu v číselníku řad dokumentů pro „Dodavatelské smlouvy“, kterou označíme například DS. Zadání do číselníku řad dokumentů V řadě nastavte všechny stavy, kterými může smlouva projít (viz tabulka v předchozím kroku) Zadání stavů - v číselníku řady dokumentů A na závěr do řady zapište kód schvalovacího postupu, který budete pro tuto řadu používat. Všimněte si, že v řadě jsou dva zvláštní stavy – „zamítnuto“ a „ukončená platnost“. Výběr schvalovacího postupu Nyní by program již generoval úkoly pro jednotlivé lidi a dokument by bylo možno si předávat. Při předání by se však nezměnil automaticky stav a navíc by bylo možno dokument stále editovat (měnit) třeba i po schválení. Proto je potřeba do systému implementovat skript, doplní automatické nastavení stavů a zamykání položek. Implementovat skript provádějící speciální funkce Skript se spouští vždy, když uživatel ukončuje svůj úkol a předává dokument dalšímu pracovníkovi. Skript vložte do editoru po zmáčknutí tlačítka „Skript po akci“ na prvním kroku schvalovacího postupu. Skript, který bude provádět požadovanou funkcionalitu, vypadá takto: //Proměnné, které mají vliv na chod skriptu či na událost po skončení skriptu: //Proměnná StepBack (typ Boolean) je předávána do skriptu a znamená, že uživatel před spuštěním skriptu provedl stisk tlačítka "Zpět" v procesu schvalování. //Proměnná StopProcess (typ Boolean), kterou je možné ze skriptu zastavit následný proces schvalování (např. po negativní validaci dat ve skriptu). Výchozí hodnota je //False. //Proměnná FinishedStepId - (typ Integer) id kroku v tabulce wfschvalpostupit na který se reaguje //Proměnná FinishedStepDataId - (typ Integer) data_id kroku v tabulce wfschvalpostupit na který se reaguje //Proměnná SelectedStepId - (typ Integer) id kroku v tabulce wfschvalpostupit který byl vybrán //Proměnná SelectedStepDataId - (typ Integer) data_id kroku v tabulce wfschvalpostupit který byl vybrán //Proměnná Trustee - (typ String) id pověřené osoby v gusers //Proměnná DeadLine - (typ Integer) počet dnů na vyřízení
var RadaCtrl: TBrowserStatic; DoklCtrl: TBrowserStatic; StavCtrl: TBrowserLookupEdit; Rada: string; Dokl_id: integer; data_id: integer; Lockflds: string;
// Procedura - zápis statusu uzamčení věty procedure WriteLockStatus(dokl_id:integer; status:string); var data_id: variant;
begin data_id := Query('Select data_id from dba._gusers',nil); ExecuteSQL('update dba.gzaznamy set fldslock = :status where id_zaznam=:dokl_id and data_id = :data_id',[status,dokl_id,data_id]); end;
// Procedura pro update dokumentu u většiny kroků procedure ProcessDoc(stav: string; dokl_id:integer; status:string); begin if dokl_id = -1 then begin StavCtrl.Text:= stav; end else begin StavCtrl.Text:= stav; WriteLockStatus(dokl_id,status); end;
end;
// -------- Hlavní část skriptu -------------------------------------------------------------------------- begin
StavCtrl := TBrowserLookupEdit(Dialog.FindComponent('LEditStav')); RadaCtrl := TBrowserStatic(Dialog.FindComponent('EditRada')); doklCtrl := TBrowserStatic(Dialog.FindComponent('EditIdZaznam')); if (StavCtrl = nil) then RaiseException('Nenalezen potřebný editační prvek.');
Rada:= RadaCtrl.Text; dokl_id := StrToInt(DoklCtrl.text); // nastavení řetězcové proměnné, která obsahuje seznam položek, které se budou na formuláři zamykat lockflds:= 'nazev, doklad, datum,pracovnik,ico_id, multi_id, autor, referent, tdoc_id, garant, dobaprezkm,platiod, platido, popis, stav, verze, dokumenty'; lockflds:=lockflds + ', DBGridPlusParams[1+2+4], DBGridUkoly[2], GridZmeny[2] ';
case SelectedStepId of 11: ProcessDoc('Rozpracováno',dokl_id,'stav'); 12: ProcessDoc('Předáno k přezkoumání',dokl_id,'stav'); 13: ProcessDoc('Přezkoumáno',dokl_id,lockflds); 14: ProcessDoc('Odesláno k podepsání',dokl_id,lockflds); 15: ProcessDoc('Zamítnuto',dokl_id,lockflds);
// vyřešení stavu "pozastaveno" -1: ProcessDoc('Ukončena platnost',dokl_id,lockflds); // zpracování posledního kroku, kdy proměnná 'SelectetStepId' vrací vždy 0
0: ProcessDoc('Platná smlouva',dokl_id,lockflds); end; end.
Všimněte si, že skript je zcela univerzální a pokud byste měli více postupů, můžete jen doplnit sekci case SelectedStepId of // doplnit kroky end; o další kroky a nemusíte tvořit další a další skripty. Tento skript by se měl zavolat na konci kteréhokoliv kroku, takže by měl být uveden u každého kroku. To je ale neefektivní a těžko udržovatelné, proto jej uveďte jen u prvního kroku, zjistěte jaký dostal název (viz obrázek) a do všech ostatních jen zapište příkaz pro zavolání právě tohoto skriptu begin ExecuteScript('System\Workflow\Postupy\ SchvalPostup00005601'); end.
Touto metodou si ušetříte hodně psaní a skript budete spravovat na jediném místě (tj. u prvního kroku). Tento skript řeší nejen přepínání stavů (viz procedura „ProcessDoc“), ale nastavuje i zamykání. Princip zamykání je shodný s principem v příkladu č.2 jen s tím rozdílem, že kód ve skriptu události „OnCreateDialog“ nevyhodnocuje sloupeček „stav“, ale přímo sloupeček „lockflds“ ve kterém je již uložen seznam fieldů k uzamčení. Skript události „OnCreateDialog“ bude vypadat podobně jako v příkladu "zamykání" : var id_zaznam,data_id: integer; Lock: Variant; Memo: TBrowserRtfMemo; lockflds:string; begin
if BrowserCommand = cmUpdate then begin id_zaznam := BrowserData.FieldByName('id_zaznam').AsInteger; data_id := BrowserData.FieldByName('data_id').AsInteger; Lock := Query('select fldslock from dba.gzaznamy where id_zaznam=:id_zaznam and data_id=:data_id', [id_zaznam, data_id]); if Lock <> Null then DisableDialogFields(BrowserDialog, Lock); end;
// základní nastavení zámku po insertu if BrowserCommand = cmInsert then begin DisableDialogFields(BrowserDialog,'stav'); end; end.
Nyní již máme zajištěno, že program dělá to, co bylo zadáním v příkladu. Navíc je otevřena cesta k dalším modifikacím skriptu, přidáním dalších postupů a vlastností. Vytvořit pohled na data podle uživatelů Posledním krokem je vytvoření pohledu, který bude obsahovat jen rozpracované dokumenty, které má přihlášený uživatel na starosti. Docílíte toho úpravou standardního pohledu „Evidence dokumentů“. Nad oknem „Evidence dokumentů“ zmáčkněte pravé tlačítko myši a zvolte funkci „Přizpůsobit“. Otevře se dialog přizpůsobení, ve kterém vyberte funkci „Datová množina“. Přizpůsobení - výběr funkce Zvolte tlačítko Přidat. Otevře se dialog pro vytvoření nového dotazu. Přidání datové množiny Doplňte název varianty a popis. Zmáčkněte OK, a ukáže se zápis SQL dotazu pro standardní pohled: SELECT id_zaznam, data_id, rada_id,doklad, datum, nazev, pracovnik, autor, referent, stav,ico_id, multi_id, (SELECT nazev1 FROM DBA.gfirmy WHERE id_ico=ico_id and id_multi = 0 AND pouz = 1) as Firma, (SELECT prijmeni+' '+jmeno+' '+titul FROM DBA.gfkontakt WHERE ico_id = ico_id AND multi_id =multi_id AND id_kontakt=autor AND nepouz = 0) as kontakt1PrijJm, (SELECT prijmeni+' '+jmeno+' '+titul FROM DBA.gfkontakt WHERE ico_id = ico_id AND multi_id =multi_id AND id_kontakt=referent AND nepouz = 0) as kontakt2PrijJm, (SELECT prijmeni+' '+jmeno FROM dba._mzosobnikarty WHERE ai=pracovnik) as pracPrijJm, (select color from dba.gzazstav as zazs where zaz.rada_id =zazs.rada_id and zaz.stav=zazs.stav), (select bgcolor from dba.gzazstav as zazs where zaz.rada_id =zazs.rada_id and zaz.stav=zazs.stav), garant,(SELECT prijmeni+' '+jmeno FROM dba._mzosobnikarty WHERE ai=garant) as garantPrijJm, platiOd,platiDo,verze,( SELECT DATEADD( month, dobaprezkm, platiod )) as terminprezk
FROM dba.gzaznamy as zaz ORDER BY rada_id,id_zaznam
Ten modifikujte (button ), kde modře označená část SQL kódu jsou přidané informace a filtr (přihlášený uživatel) pro výběr množiny dat: SELECT id_zaznam, data_id, rada_id,doklad, datum, nazev, pracovnik, autor, referent, stav,ico_id, multi_id, (SELECT nazev1 FROM DBA.gfirmy WHERE id_ico=ico_id and id_multi = 0 AND pouz = 1) as Firma, (SELECT prijmeni+' '+jmeno+' '+titul FROM DBA.gfkontakt WHERE ico_id = ico_id AND multi_id =multi_id AND id_kontakt=autor AND nepouz = 0) as kontakt1PrijJm, (SELECT prijmeni+' '+jmeno+' '+titul FROM DBA.gfkontakt WHERE ico_id = ico_id AND multi_id =multi_id AND id_kontakt=referent AND nepouz = 0) as kontakt2PrijJm, (SELECT prijmeni+' '+jmeno FROM dba._mzosobnikarty WHERE ai=pracovnik) as pracPrijJm, (select color from dba.gzazstav as zazs where zaz.rada_id =zazs.rada_id and zaz.stav=zazs.stav), (select bgcolor from dba.gzazstav as zazs where zaz.rada_id =zazs.rada_id and zaz.stav=zazs.stav), garant,(SELECT prijmeni+' '+jmeno FROM dba._mzosobnikarty WHERE ai=garant) as garantPrijJm, platiOd,platiDo,verze,( SELECT DATEADD( month, dobaprezkm, platiod )) as terminprezk,
(select first w.nazev from dba.wfukoly as w where (cast(id_zaznam as char)||';'||cast(data_id as char)||';'||rada_id) = w.doklad and w.typ_vazby=4 order by w.id DESC) as Dalsi_krok,
(select first w.termin from dba.wfukoly as w where (cast(id_zaznam as char)||';'||cast(data_id as char)||';'||rada_id) = w.doklad and w.typ_vazby=4 order by w.id DESC) as Termin,
(select p.Prijmeni||' '||p.Jmeno from dba._mzosobnikarty as p where p.ai = (select first osoba_id from dba.wfukoly as w where (cast(id_zaznam as char)||';'||cast(data_id as char)||';'||rada_id) = w.doklad and w.typ_vazby=4 order by w.id DESC) and data_id = (select first osoba_data_id from dba.wfukoly as w where (cast(id_zaznam as char)||';'||cast(data_id as char)||';'||rada_id) = w.doklad and w.typ_vazby=4 order by w.id DESC)) as Povereny_prac
FROM dba.gzaznamy as zaz
WHERE (select first osoba_id from dba.wfukoly as w where (cast(id_zaznam as char)||';'||cast(data_id as char)||';'||rada_id) = w.doklad and w.typ_vazby=4 order by w.id DESC) = (select person_id from dba._gusers)
ORDER BY rada_id,id_zaznam
Touto modifikací zajistíte, že standardní pohled zobrazující všechny dokumenty nově zobrazí jen dokumenty, které má právě přihlášený uživatel na starosti a zároveň přidáte do pohledu další tři sloupce „Další_krok“, „Termin“ a „Povereny_prac“. Tyto tři sloupce pocházejí z úkolů workflow a říkají, kdo, do kdy a co má s dokumentem udělat. Seznam dokumentů, kde autor dokumentu je Nováková Renata (dle zadaného systémového uživatele) Tím je implementace požadované funkcionality kompletní. A můžeme vyzkoušet výše zadanou funkcionalitu:
Dokument je rozpracovaný a každá část se dá editovat. Přihlášený pracovník bude v pohledu „Moje smlouvy“ vidět jen svoje záznamy.
Otevře formulář a použije klávesu „Ctrl F2 – Předání, schválení“. Program vyvolá dialog pro předání. Uživatel A zde jen doplní poznámku o vyřízení a zvolí uživatele, kterého žádá o přezkoumání. Po zmáčknutí OK, se dialog uzavře včetně formuláře dokumentu a uživateli A zmizí dokument z jeho pohledu. Dokument se opačně objeví v pohledu uživatele B, který bude dokument přezkoumávat (dokument již bude ve stavu „Předáno k přezkoumání“). Stejným způsobem bude probíhat další předávání. Jakmile se dokument dostane do stavu přezkoumáno, zamknou se automaticky všechny položky na formuláři a již nebude možno měnit obsah dokumentu. O celé historii předávání je vedena podrobná evidence a kdykoliv je možno zpětně zjistit, kdo co a kdy s dokumentem udělal. Příklad, který jsme právě prezentovali, neřešil větvení procesů, zastavování procesů, vracení kroků zpět a podobně. Všechny tyto možnosti program ošetřuje a lze je drobnou modifikací nastíněných metod též implementovat. Související témata |