| | 1 | |
| | 2 | = Rejestry = |
| | 3 | |
| | 4 | == Tworzenie rejestru == |
| | 5 | Aby założyć rejestr w module rejestry musimy rozpocząć od założenia tabeli. Tabelę tworzymy za pomocą komendy ''create table''. |
| | 6 | |
| | 7 | Przykład założenia tabeli |
| | 8 | {{{ |
| | 9 | -- Table: cregisters.creg_r_imi |
| | 10 | |
| | 11 | -- DROP TABLE cregisters.creg_r_imi; |
| | 12 | |
| | 13 | CREATE TABLE cregisters.creg_r_imi |
| | 14 | ( |
| | 15 | -- Odziedziczony from table cregisters.register_entry: id____ integer NOT NULL DEFAULT nextval('cregisters.register_entry_id_____seq'::regclass), |
| | 16 | -- Odziedziczony from table cregisters.register_entry: cregid integer, |
| | 17 | -- Odziedziczony from table cregisters.register_entry: uid___ text, |
| | 18 | -- Odziedziczony from table cregisters.register_entry: is_del boolean NOT NULL DEFAULT false, |
| | 19 | -- Odziedziczony from table cregisters.register_entry: adduid integer, |
| | 20 | -- Odziedziczony from table cregisters.register_entry: adddat timestamp with time zone DEFAULT now(), |
| | 21 | -- Odziedziczony from table cregisters.register_entry: lm_uid integer, |
| | 22 | -- Odziedziczony from table cregisters.register_entry: lm_dat timestamp with time zone DEFAULT now(), |
| | 23 | -- Odziedziczony from table cregisters.register_entry: doc_id integer, |
| | 24 | -- Odziedziczony from table cregisters.register_entry: prc_id integer, |
| | 25 | -- Odziedziczony from table cregisters.register_entry: cre_id integer, |
| | 26 | vorgnr character varying(25) NOT NULL, |
| | 27 | rwa character varying(20) NOT NULL, |
| | 28 | zrodlo character varying(50), |
| | 29 | rodzaj character varying(50), |
| | 30 | terminod timestamp without time zone, |
| | 31 | termindo timestamp without time zone, |
| | 32 | nazwa character varying(250), |
| | 33 | ulica character varying(80), |
| | 34 | budnr character varying(10), |
| | 35 | kwota double precision, |
| | 36 | archiv boolean NOT NULL DEFAULT false, |
| | 37 | status smallint NOT NULL DEFAULT 0, |
| | 38 | edtuser character varying(50), |
| | 39 | edtdate timestamp without time zone, |
| | 40 | id serial NOT NULL |
| | 41 | -- Odziedziczony from table : tpstid integer, |
| | 42 | -- Odziedziczony from table : stcuid integer, |
| | 43 | -- Odziedziczony from table : stcdat timestamp with time zone |
| | 44 | ) |
| | 45 | INHERITS (cregisters.register_entry) |
| | 46 | WITH ( |
| | 47 | OIDS=FALSE |
| | 48 | ); |
| | 49 | ALTER TABLE cregisters.creg_r_imi |
| | 50 | OWNER TO edokumenty; |
| | 51 | GRANT ALL ON TABLE cregisters.creg_r_imi TO edokumenty; |
| | 52 | GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE cregisters.creg_r_imi TO http; |
| | 53 | GRANT SELECT, UPDATE ON TABLE cregisters.creg_r_imi TO useraspbip; |
| | 54 | }}} |
| | 55 | |
| | 56 | '''Uwaga ! Pola używane przez eDokumenty są dziedziczone - nie trzeba ich zakładać. Są to pola: |
| | 57 | {{{ |
| | 58 | id____, cregid, uid___, is_del, adduid, adddat, lm_uid, lm_dat, doc_id, prc_id, cre_id, tpstid, stcuid, stcdat |
| | 59 | }}} |
| | 60 | ''' |
| | 61 | |
| | 62 | '''Uwaga ! Nie zapominamy o nadaniu uprawnień do tabeli dla edokumenty, useraspbip oraz http''' |
| | 63 | |
| | 64 | Następnie w module rejestry zakładamy nowy rejestr, a w polu nazwa tabeli wprowadzamy nazwę założonej tabeli. System będzie od nas żądać, aby nazwa tabeli rozpoczynała się od "creg_". |
| | 65 | |
| | 66 | == Tworzenie raportu == |
| | 67 | Po utworzeniu tabeli w schema cregisters rozpoczynającej się od ciągu creg_ należy utworzyć raport np: |
| | 68 | |
| | 69 | {{{ |
| | 70 | SELECT ('CREGISTER_ENTRY') AS clsnam, cd.id____ AS keyval, cd.* |
| | 71 | FROM cregisters.creg_ddm_dokumenty cd |
| | 72 | INNER JOIN cregisters.creg_archiv_formularz af ON cd.menuid = af.formularz |
| | 73 | WHERE {FILTER_STRING} AND cd.is_del IS NOT true |
| | 74 | {ORDER_BY} |
| | 75 | {LIMIT} |
| | 76 | }}} |
| | 77 | |
| | 78 | |
| | 79 | |
| | 80 | Raport należy podlinkować do rejestru ustawiając w tabeli registers pole rep_id. |
| | 81 | |
| | 82 | == Ważne tabele == |
| | 83 | |
| | 84 | {{{ |
| | 85 | registers (klucz główny: ) |
| | 86 | registers_entry (klucz głowny: , klucz obcy: ) |
| | 87 | register_fields (klucz główny: , klucz obcy: ) |
| | 88 | }}} |
| | 89 | |
| | 90 | Uwaga! Kluczem obcym w registers_entry referujacym do rejestru jest XXXX |
| | 91 | |
| | 92 | == Rejestr jako lista w dokumencie == |
| | 93 | |
| | 94 | Definiujemy powiązanie rejestru z typem dokumentu (jeżeli na to być lista a nie formularz to ustawiamy parametr ''collection'' na ''true''): |
| | 95 | {{{ |
| | 96 | INSERT INTO cregisters.register_links (cregid, keyval, clsnam, params) |
| | 97 | VALUES ({cregisters.register.id____}, {types_of_documents.dctpid}, 'DOCUMENT', '{"collection":true}') |
| | 98 | }}} |
| | 99 | == Podrejestr w rejestrze == |
| | 100 | Aby zbudować strukturę hierarchiczną rejestru wystarczy zlinkować odpowiednio 2 wcześniej utworzone rejestry. Pierwszy ze wskazanych zacznie się pojawiać jako lista rekordów w formatce rejestru nadrzędnego. |
| | 101 | {{{ |
| | 102 | INSERT INTO cregisters.register_links (cregid, keyval, clsnam, params) |
| | 103 | VALUES ({cregisters.register.id____}, {cregisters.register.id____}, 'CREGISTER', '{"collection":true}') |
| | 104 | }}} |
| | 105 | ''' |
| | 106 | Uwaga! Id podrejestru jest wprowadzany w insercie jako pierwsze, następny jest id rejestru do którego będzie należeć podrejestr.''' |
| | 107 | |
| | 108 | W raporcie w podrejestrze za filtrowanie rekordów odpowiada makro {FILTER_STRING}, które dokleja do zapytania warunek po atrybucie cre_id (cre_id wskazuje na rekord rejestru nadrzędnego). |
| | 109 | |
| | 110 | == Definicje pól dla rejestru == |
| | 111 | |
| | 112 | === Ustawianie wartości domyślnych === |
| | 113 | |
| | 114 | Jeżeli chcemy aby pole było listą wyboru, to definiujemy w parametrach (register_fields.params) domyślną wartość (defaultValue): |
| | 115 | |
| | 116 | {{{ |
| | 117 | -- Id tworzącego dokument |
| | 118 | {"defaultValue":"{SQL::SELECT adduid FROM documents WHERE doc_id = {doc_id}}"} |
| | 119 | |
| | 120 | -- domyślne dane zalogowanego użytkownika |
| | 121 | {"defaultValue":"{SQL::SELECT o.firnam || ' ' || o.lasnam || ' (' || COALESCE(o.orunsm, '') || ' - ' || o.ndenam || ')' AS wytworzyl FROM orgtree_view o WHERE o.usr_id = {LOGGED_USR_ID}}"} |
| | 122 | |
| | 123 | }}} |
| | 124 | |
| | 125 | Możliwe jest też ustawienie wartości wyliczanej za każdym razem gdy dokonujemy zapisu rejestru (dla pól ukrytych): |
| | 126 | |
| | 127 | {{{ |
| | 128 | -- Imię i nazwisko dokonującego zmian w rejestrze |
| | 129 | {"value":"{SQL::select firnam || ' ' || lasnam from users where usr_id={LOGGED_USR_ID}}"} |
| | 130 | }}} |
| | 131 | |
| | 132 | 1. '''defaultValue''' jest parsowane tylko dla formularza nowego wpisu w rejestrze (na akcji Open oraz Save).[[BR]] |
| | 133 | 2. '''value''' jest parsowane zawsze na akcji Save niezależnie od trybu (edycja, nowy) wyłącznie dla pól: |
| | 134 | a. ukrytych poprzez definicję pola (register_fields.hidden = TRUE) |
| | 135 | b. ukrytych poprzez parametr visible (register_fields.params = {"visible":false}) |
| | 136 | c. nieaktywnych (register_fields.params = {"enabled":false}) |
| | 137 | |
| | 138 | |
| | 139 | === Pole jako lista wyboru === |
| | 140 | |
| | 141 | Jeżeli chcemy aby pole było listą wyboru, to definiujemy w parametrach (register_fields.params) zapytanie zwracające rekordy typu (klucz,wartość), dodatkowo ustawiamy domyślną wartość (defaultValue): |
| | 142 | |
| | 143 | {{{ |
| | 144 | {"sql":"SELECT usr_id,usrnam FROM users WHERE is_del IS NOT TRUE", "defaultValue":"{SQL::SELECT adduid FROM documents WHERE doc_id = {doc_id}}"} |
| | 145 | }}} |
| | 146 | Parametry: sql, defaultValue, są objęte standardowym mechanizmem parsowania [http://support.edokumenty.eu/trac/wiki/DeployerGuide/Customization#a3.5Parametry parametrów] (tak jak np. w przypisaniach w [http://support.edokumenty.eu/trac/wiki/DeployerGuide/Customization/ProcessAutomation workflow]). |
| | 147 | |
| | 148 | === Pole tekstowe typu HTML === |
| | 149 | |
| | 150 | {{{ |
| | 151 | {"type":"html"} |
| | 152 | }}} |
| | 153 | |
| | 154 | === Pole tekstowe typu !ComboBox === |
| | 155 | |
| | 156 | |
| | 157 | {{{ |
| | 158 | {"type":"combobox","autoSearch":2,"sql":"SELECT usr_id,usrnam FROM users WHERE is_del IS NOT TRUE AND (firnam ~* E'^{SEARCH_TEXT}')"} |
| | 159 | }}} |
| | 160 | Znacznik {SEARCH_TEXT} zostanie zastąpiony wpisanym w pole tekstem[[BR]] |
| | 161 | 1. autoSearch - ilosc znaków po których wpisaniu zostanie uruchomione wyszukiwanie / podpowiadanie (wartość -1 spowoduje wyłączenie automatycznego wyszukiwania i pokazanie ikony lupki) |
| | 162 | |
| | 163 | |
| | 164 | === Pole jako status === |
| | 165 | |
| | 166 | W definicji pola, w polu Alias wpisujemy "tpstid" |
| | 167 | |
| | 168 | |
| | 169 | === Disablowanie pola === |
| | 170 | Jeśli pole ma być tylko do odczytu to należy dla niego określić atrybut enabled: |
| | 171 | {{{ |
| | 172 | {"enabled":false} |
| | 173 | }}} |
| | 174 | |
| | 175 | === !ToolBar === |
| | 176 | |
| | 177 | {{{ |
| | 178 | {"type":"toolbutton","icon":"new.gif","visible":1,"doRefresh":true,"onclick":["moj_skrypt.inc","MojaKlasa1","mojaFunkcja",{"parametr_1":"aqq","parametr_2":"{register_entry.adddat}"}]} |
| | 179 | }}} |
| | 180 | 1. icon: plik ikony bez ścieżki która wskazuje domyślnie na ./img/toolbarIcons/24x24/ |
| | 181 | Skrypt "app/edokumenty/scripts/moj_skrypt.inc" |
| | 182 | 2. doRefresh: wartość true spowoduje przeładowanie formularza wpisu w rejestrze |
| | 183 | |
| | 184 | {{{ |
| | 185 | <?php |
| | 186 | class MojaKlasa1 { |
| | 187 | |
| | 188 | public function __construct() { |
| | 189 | } |
| | 190 | |
| | 191 | public function mojaFunkcja($params) { |
| | 192 | $params = json_decode($params,TRUE); |
| | 193 | |
| | 194 | jscript::alert(json_encode($params)); |
| | 195 | } |
| | 196 | } |
| | 197 | ?> |
| | 198 | }}} |
| | 199 | |
| | 200 | Wywołanie / otwarcie formularza poprzez clsnam i keyval (np. otwarcie tego samego wpisu w nowym oknie czyli edycja): |
| | 201 | {{{ |
| | 202 | {"type":"toolbutton","icon":"edit.gif","enabled":1,"onclick":["","Application","openDialogByCls","","CREGISTER_ENTRY","SQL::SELECT {cregisters.creg_przykladowy_rejestr.id____}"]} |
| | 203 | }}} |
| | 204 | |
| | 205 | Usuń wpis z rejestru: |
| | 206 | {{{ |
| | 207 | {"type":"toolbutton","icon":"del.gif","enabled":1,"onclick":["","Application","openDialogByCls",{"mode":"del"},"CREGISTER_ENTRY","SQL::SELECT {cregisters.creg_przykladowy_rejestr.id____}"]} |
| | 208 | }}} |
| | 209 | |
| | 210 | == Filtrowanie listy == |
| | 211 | Dla rejestru można ustawić stały filtr w parametrach (cregisters.register.params) |
| | 212 | {{{ |
| | 213 | {"FILTER_STRING":"is_del IS TRUE"} |
| | 214 | }}} |
| | 215 | |
| | 216 | |
| | 217 | == Modyfikacje JSON bezpośrednio w bazie danych == |
| | 218 | |
| | 219 | Sposób na zmianę wartości jednego pola w obiekcie typu JSON ('''dla PostgreSQL v9.3+'''): |
| | 220 | {{{ |
| | 221 | CREATE OR REPLACE FUNCTION "json_set_value"( |
| | 222 | "json" json, |
| | 223 | "key_to_set" TEXT, |
| | 224 | "value_to_set" anyelement |
| | 225 | ) |
| | 226 | RETURNS json |
| | 227 | LANGUAGE sql |
| | 228 | IMMUTABLE |
| | 229 | STRICT |
| | 230 | AS $function$ |
| | 231 | SELECT COALESCE( |
| | 232 | (SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}') |
| | 233 | FROM (SELECT * |
| | 234 | FROM json_each("json") |
| | 235 | WHERE "key" <> "key_to_set" |
| | 236 | UNION ALL |
| | 237 | SELECT "key_to_set", to_json("value_to_set")) AS "fields"), |
| | 238 | '{}' |
| | 239 | )::json |
| | 240 | $function$; |
| | 241 | |
| | 242 | UPDATE cregisters.register_field SET params = json_set_value(params, 'doRefresh', true) WHERE id____ = 1; |
| | 243 | |
| | 244 | UPDATE cregisters.register_field SET params = json_set_value(params, 'value', 'SQL::SELECT ''tekst "kolo"''') WHERE id____ = 1; |
| | 245 | }}} |
| | 246 | |
| | 247 | |
| | 248 | == Migracja rejestrów z innej bazy == |
| | 249 | |
| | 250 | [wiki:UserGuide/AdvancedConfiguration/CustomRegisters/Import Import rejestrów] |
| | 251 | |
| | 252 | == Przydatne konstrukcje i zapytania == |
| | 253 | {{{ |
| | 254 | -- użycie w parametrach do przycisków i pól wartości {DOC_ID} powoduje błąd po wejściu na rekord rejestru jeśli jest pusty. Aby temu zapobiec należy obłożyć {DOC_ID} konstukcją NULLIF i COALESCE. |
| | 255 | select pprosm from documents where doc_id = COALESCE(NULLIF('{DOC_ID}',''),'0')::int |
| | 256 | |
| | 257 | }}} |