Compare commits

..

72 Commits

Author SHA1 Message Date
Josef Rokos 893b665dc2 V ověření proti AD lze nyní nastavit UPN suffix pro vyhledání objektu uživatele v AD. Pokud uživatel se zadaným suffixem nebude nalezen, použije se jako suffix název domény. 6 years ago
Josef Rokos 2a48f440af V agendách pro schválení materiálu a služeb se na záložce "Mé komise" objevuje informace o vyčerpaném limitu komise. 6 years ago
Josef Rokos e55d7ad07f Optimalizace načítání gridů při otevření přes URL. Entita TripBill se cachuje přes Hibernate Cache. 6 years ago
Josef Rokos 48bd9983fc Optimalizace načítání gridů cestovních příkazů. 6 years ago
Josef Rokos c72ab99dc1 Povýšení verze. 6 years ago
Josef Rokos 4dbe7c47f8 Přidány sestavy pro přehledy o vyúčtovaných a nevyúčtovaných cestovních příkazech. 6 years ago
Josef Rokos 1aeff7f587 Do gridů v cestovních příkazech byly přidány sloupce "Počátek sl. cesty", "Spolucestující" a "Datum schválení". 6 years ago
Josef Rokos 70a2e01fae Opravena chyba výpočtu stravného u celodenního cesťáku.
closes #279
8 years ago
František Přibyl fcb8db25fa Upraven styl vybraného záznamu nebo HOVER záznamu.
closes #273
8 years ago
František Přibyl 740847e865 Implementováno filtrování datového typu BigDecimal do gridů požadavků.
closes #272
8 years ago
Josef Rokos 093d359df7 Po refreshi gridu se obnovi puvodni trideni a filtr nastaveny pred editaci/schvalenim zaznamu.
closes #271
9 years ago
Josef Rokos ea2708f303 Opraveno rušení schválení vyúčtování SC z agendy požadavků
closes #270
9 years ago
Josef Rokos 9b2e2b3641 Oprava predesloho commitu.
refs #269
9 years ago
Josef Rokos a8dc7f1306 Opravena chyba zacyklani requestu pri trideni gridu s vybranym zaznamem.
Nasazani cache entit.
closes #269
9 years ago
Josef Rokos 7d4d693b2e Opraveno mazani zaznamu s neexistujicim pripojenym dokumentem. 9 years ago
Josef Rokos e4013f44ab Úprava sestavy vyúčtování služební cesty.
closes #268
9 years ago
Josef Rokos b95cac9ef1 U gridů ve fakturaci bylo nastaveno stránkování.
Oprava buildu.
closes #267
9 years ago
Josef Rokos 5079d6d55a Merge branch 'master' of https://git.bukova.info/repos/git/isspst 9 years ago
Josef Rokos a93c515bc0 Přidány nové tiskové sestavy "Protokol předběžné kontroly" do agend Fakturace požadavků a Požadavky na služební cesty. 9 years ago
Josef Rokos 1475babaa1 Vylepšeno logování chyb při generování sestav.
Sestavám se nastavuje locales pro formátování čísel z nastavení prohlížeče.
9 years ago
Josef Rokos b0fb32825b Opravena chyba při vytváření vyúčtování služební cesty a požadavku na schválení cesťáku- na záznamech se nenastavovalo období.
Opraveno filtrování nabízených středisek.
9 years ago
František Přibyl 9d59b34900 Merge remote-tracking branch 'origin/master' 9 years ago
František Přibyl 47e90b4287 Do podepsaných dokumentů implementována záložka pro archivaci souborů do ZIP.
closes #265
9 years ago
Josef Rokos b276746bac Změněn popisek pole "Zpráva o výsledku pracovní cesty"
closes #260
9 years ago
Josef Rokos f938403cea Byl omezen výběr středisek u nového požadavku, aby bylo zamezeno schvalování sobě samému.
closes #266
9 years ago
Josef Rokos b321b3e25f Opraven start na prázdné databázi. 9 years ago
Josef Rokos cbb81657c8 Přidaná agenda pro nastavení limitů komisí. Změněn způsob hlídání limitů při zadávání nového požadavku- limit se bere z nové agendy.
closes #263
closes #264
9 years ago
Josef Rokos cd6b8c01dc Merge branch 'master' of https://git.bukova.info/repos/git/isspst 9 years ago
Josef Rokos 012ad06358 Implementovano prepinani ciselnych rad podle obdobi.
closes #262
9 years ago
František Přibyl 88e9711154 Implementován obecný export prvků Listbox do excelu.
closes #261
9 years ago
Josef Rokos d2aa1cbd9a Opraveno vyhodnocení sestavy pro podpis, pokud je v agendě více sestav s podpisem. 9 years ago
Josef Rokos 52cf63414b Oprevena sestava Žádost o SC- tisk z agend Cestovní příkazy a Požadavky na SC odkazuje na stejnou sestavu.
Byla přidána možnost použít property hlavní entity jako zdroje dat pro sestavu- rozšířen constructor třídy Report o parametr property.
9 years ago
Josef Rokos f904e89946 Opraveno filtrování podle čísla požadavku v agendě Cestovní příkazy. 9 years ago
Josef Rokos 5cae516cb6 Na sestavě Vyúčtování SC bylo odstraněno pole pro podpis "S provedením pracovní cesty souhlasí".
closes #259
9 years ago
Josef Rokos 6ac6d783fb - Opravena kontrola práv při ružení schválení vyúčtování SC.
- Opraven refresh gridů při mazání záznamů.
- Zrušeno výchozí třídění v agendě Cestovní příkazy.
- Opraven pom.xml.
9 years ago
Josef Rokos 67ff54d3f1 Merge branch 'master' of https://git.bukova.info/repos/git/isspst 9 years ago
Josef Rokos 275e120021 Opraveno ukládání záznamu v agendě Fakturace požadavků. Příznak Fakturováno se již ukládá správně. 9 years ago
František Přibyl d20a72b336 Kvůli přechodu na IntelliJ IDEA upravena konfigurace Maven.
Fakturace rozděleny na fakturace materiálu a služeb.

closes #249
9 years ago
Josef Rokos e24684bbd0 Přesunut podpis příkazce operace na vyúčtování služební cesty.
closes #258
9 years ago
Josef Rokos 21bf006c19 Aktualizace podepisovací komponenty. 9 years ago
Josef Rokos 970928bb4e Merge branch 'master' of https://git.bukova.info/repos/git/isspst 9 years ago
Josef Rokos 369184940b Do agendy Cestovní příkazy byly přidány záložky "Má střediska", "Mé komise" a "Vše", kde se zobrazují vyúčtování služebních ke schválení. V záložkách lze vyúčtování označit jako proplacené. Do e-mailu se generuje odkaz do těchto záložek.
closes #253
closes #250
9 years ago
František Přibyl cc374a3bf1 Podepsané dokumenty se nyní zobrazují ve dvou záložkách - Aktuální
dokumenty a Archiv.
V Archivu se zobrazují dokumenty starší než rok.

closes #225
9 years ago
František Přibyl 66e0c427ac Popisek změněn na "Zajistím sám", případně ve sloupci na "Zaj. sám"
closes #247
9 years ago
František Přibyl 095089d020 U požadavků na nákup je nyní pole Popis povinné.
closes #248
9 years ago
Josef Rokos 84154ccbff Neaktivní uživatelé se nenabízí v seznamech pro výběr uživatele (spolucestující...). V agendě Uživatelé a Střediska/komise jsou barevně odlišeni.
closes #239
9 years ago
Josef Rokos 1230959854 Opraveno duplikování vyúčtování SC, když se na požadavku provede úprava a znovu se schválí.
closes #255
9 years ago
Josef Rokos 96154a6b98 Opraveno mazání záznamů z požadavků
closes #257
9 years ago
Josef Rokos 14242fa41a Vyúčtování služebních cest u spolucestujících lze nyní zrušit u každého zvlášť. Lze tak provést dodatečnou opravu vyúčtování.
closes #251
9 years ago
Josef Rokos 67a99d8d78 Na sestavách se pro viditelný dig. podpis vytváří klasické read only formulářové pole, které se podpisem nahradí za obrázek podpisu.
Změna podepisovací komponenty- na windows se spouští stejná jak na linuxu, macos...
closes #244
9 years ago
Josef Rokos 768d3ee874 Opraveno duplicitní vkládání záznamů do agendy Fakturace požadavků, v případě, že se požadavek upraví a znovu schválí.
closes #252
9 years ago
Josef Rokos cd6a6cf5a6 Přidaná sestava "Protokol o kontrole" - digitální podpis při schvalování nákupů. 9 years ago
Josef Rokos d1ccaf530d Při napojování uživatele z AD se login převede na malá písmena. Opravena chyba při mazání uživatele.
closes #237
9 years ago
Josef Rokos 10439b5001 Merge branch 'master' of https://git.bukova.info/repos/git/isspst 9 years ago
Josef Rokos b33f9f2e8a Pokud se upraví požadavek, u kterého je podepsaný dokument, tak se dokument smaže a požadavek se nastaví jako nový.
closes #227
9 years ago
František Přibyl 07d0949bea Merge branch 'master' of https://git.bukova.info/repos/git/isspst 10 years ago
František Přibyl 2819cc125c Implementován validátor pro Globální nastavení.
closes #236
10 years ago
Josef Rokos c0922921c5 V agendě Procesy schválení lze u jednotlivých schvalovacích rolí nastavit, jestli bude vyžadován při schválení elektronický podpis.
closes #242
10 years ago
Josef Rokos b70041bfff Změněn způsob ukládání PDF dokumentu. Data se předávájí ve ViewModelu, tak nemůže dojít k tomu, že by se schválením jiného záznamu v druhém okně prohlížeče uložilo jiné PDF.
refs #243
10 years ago
Josef Rokos b5ffa07644 Aktualizace podepisovací aplikace- opraveno náhodné zatuhnutí po startu.
refs #224
10 years ago
Josef Rokos cccd8177fa Implementace uložiště podepsaných dokumentů. Při prvním podpisu se uloží podepsané PDF a vytvoří se záznam v agendě podepsaných dokumentů.
closes #243
10 years ago
Josef Rokos 6db416dd04 Vyřešeno generování PDF pro podpis na základě entity, která se schvaluje.
closes #240
10 years ago
Josef Rokos 05faa87071 Digitální podpis se zobrazí v PDF viditelně. Server předá podepisovací aplikaci ID fieldu, kde se podpis zobrazí. ID je zadáno v reportu jaku parametr pole signature.
refs #224
10 years ago
Josef Rokos 11e3a48b28 Ve windows se spustí podepisovací aplikace, která si bere certifikáty ze systémového uložiště.
refs #224
10 years ago
Josef Rokos d7999e78ca Merge remote-tracking branch 'origin/master' 10 years ago
Josef Rokos d6cff454fd Základní implementace podepisování PDF dokumentů. Podpis implementován pouze pro sestavu schválení služební cesty (natvrdo v kódu). Spouští se univerzální podepisovací aplikace, která čte certifikát ze souboru.
closes #224
10 years ago
František Přibyl 1d30f0d0c7 Merge branch 'master' of https://git.bukova.info/repos/git/isspst 10 years ago
František Přibyl 9fb1ef7601 Přidána základní funkčnost zobrazování dat agendy.
refs #225
10 years ago
Josef Rokos 312b62af7b Merge branch 'Verze_2.0' 10 years ago
Josef Rokos 162cea6001 Merge branch 'Verze_2.0' 10 years ago
Josef Rokos 1164e11107 Merge branch 'master' of https://git.bukova.info/repos/git/isspst 10 years ago
František Přibyl c9a56887dc Připraveny podklady pro novou agendu "Podepsané dokumenty"
Vzhled agendy (grid/strom/...) zatím není znám.

closes #222
10 years ago

@ -0,0 +1,79 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 16464111046498525641 (0xe47c45c4252121c9)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=CZ, ST=Vysocina, O=bukova.info, CN=Josef Rokos/emailAddress=rokos@bukova.info
Validity
Not Before: Jun 24 09:59:50 2015 GMT
Not After : Jun 21 09:59:50 2025 GMT
Subject: C=CZ, ST=Vysocina, O=bukova.info, CN=Josef Rokos/emailAddress=rokos@bukova.info
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:bc:fb:64:50:5b:58:03:8c:20:1c:77:d3:50:31:
94:55:78:d6:05:bb:bc:88:9d:cb:20:b1:8c:ff:ac:
fc:97:1a:b1:9c:29:c4:ac:af:ed:3b:de:93:d5:cf:
75:3e:d0:05:41:32:bf:12:25:53:60:28:af:ff:3e:
3c:3a:4c:52:78:3f:b2:78:b9:c6:2f:fc:0e:44:eb:
65:c3:7f:38:2b:ab:88:37:8c:68:55:69:e3:3d:5e:
9b:99:25:11:55:06:ab:e8:c1:fa:54:da:5b:e7:9b:
3e:3f:39:4f:cf:b3:cb:48:cf:96:02:89:0b:7e:24:
c7:00:e9:ce:8d:ea:07:cf:21:f2:89:51:c8:cc:7a:
04:e4:68:6f:1c:a8:e0:76:18:40:62:ee:2f:bd:13:
64:b7:1e:2e:18:bb:b1:d4:17:d5:fb:1f:07:59:65:
46:f0:c4:51:dc:ac:62:ff:31:a8:72:26:a6:1a:88:
37:23:82:49:9a:02:d2:39:74:98:71:7f:a4:77:52:
3a:ed:22:2e:99:9c:81:2c:48:16:3c:82:7b:af:2c:
0d:4b:28:4d:e0:46:7d:b5:b8:ea:3f:e7:5a:5b:4f:
d8:06:b2:a3:86:2f:8b:5b:9c:bc:04:2e:64:b6:e1:
09:c9:14:6d:54:7e:86:40:7b:66:33:27:33:4a:3d:
7c:97
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
EF:9B:88:5C:07:27:79:EA:60:90:5C:7A:28:45:FB:7F:35:E6:CB:3F
X509v3 Authority Key Identifier:
keyid:EF:9B:88:5C:07:27:79:EA:60:90:5C:7A:28:45:FB:7F:35:E6:CB:3F
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
08:e9:a4:32:cc:35:7c:66:5a:ea:f2:bd:e6:75:78:81:52:11:
22:27:32:c9:ec:91:6e:51:8a:f1:1e:0f:25:8a:e1:64:ba:e4:
85:1c:e4:fd:75:f0:26:3d:65:62:16:29:20:4f:5f:d2:66:36:
de:2b:bd:7b:96:71:f6:2c:d1:c5:54:69:89:dd:52:20:49:49:
b1:ac:09:b4:1e:33:59:0d:89:fd:a4:28:7a:70:96:e5:cb:58:
7e:b9:1d:02:7a:33:ee:ad:6a:ad:2c:3c:5e:7d:cc:f5:72:69:
51:fd:77:b4:0f:10:fd:9e:c2:1a:04:c5:a9:56:6e:fd:66:9f:
b6:1c:f9:d3:68:f4:4f:8c:6c:67:af:f5:e0:a5:30:67:a6:a7:
9b:6e:16:89:8a:e5:b4:20:f4:f7:74:f4:9c:ca:5d:c7:2f:e6:
30:9d:6b:2e:95:29:c1:e7:aa:d7:d6:59:dc:a9:f0:10:40:02:
66:3f:58:a2:38:8c:89:1a:0b:94:1a:e5:80:49:14:44:f4:06:
b1:11:1a:cd:ef:76:6a:bf:f8:6f:58:9d:af:a3:6b:9a:8e:bb:
6c:10:d6:d8:4e:73:58:20:0b:99:38:41:d4:22:d4:80:0b:09:
0d:25:40:3e:66:15:a0:44:4e:d6:59:5a:58:07:e5:4b:62:f1:
e9:ae:b6:7c
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIJAOR8RcQlISHJMA0GCSqGSIb3DQEBBQUAMG4xCzAJBgNV
BAYTAkNaMREwDwYDVQQIDAhWeXNvY2luYTEUMBIGA1UECgwLYnVrb3ZhLmluZm8x
FDASBgNVBAMMC0pvc2VmIFJva29zMSAwHgYJKoZIhvcNAQkBFhFyb2tvc0BidWtv
dmEuaW5mbzAeFw0xNTA2MjQwOTU5NTBaFw0yNTA2MjEwOTU5NTBaMG4xCzAJBgNV
BAYTAkNaMREwDwYDVQQIDAhWeXNvY2luYTEUMBIGA1UECgwLYnVrb3ZhLmluZm8x
FDASBgNVBAMMC0pvc2VmIFJva29zMSAwHgYJKoZIhvcNAQkBFhFyb2tvc0BidWtv
dmEuaW5mbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALz7ZFBbWAOM
IBx301AxlFV41gW7vIidyyCxjP+s/JcasZwpxKyv7Tvek9XPdT7QBUEyvxIlU2Ao
r/8+PDpMUng/sni5xi/8DkTrZcN/OCuriDeMaFVp4z1em5klEVUGq+jB+lTaW+eb
Pj85T8+zy0jPlgKJC34kxwDpzo3qB88h8olRyMx6BORobxyo4HYYQGLuL70TZLce
Lhi7sdQX1fsfB1llRvDEUdysYv8xqHImphqINyOCSZoC0jl0mHF/pHdSOu0iLpmc
gSxIFjyCe68sDUsoTeBGfbW46j/nWltP2Aayo4Yvi1ucvAQuZLbhCckUbVR+hkB7
ZjMnM0o9fJcCAwEAAaNQME4wHQYDVR0OBBYEFO+biFwHJ3nqYJBceihF+3815ss/
MB8GA1UdIwQYMBaAFO+biFwHJ3nqYJBceihF+3815ss/MAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAjppDLMNXxmWuryveZ1eIFSESInMsnskW5RivEe
DyWK4WS65IUc5P118CY9ZWIWKSBPX9JmNt4rvXuWcfYs0cVUaYndUiBJSbGsCbQe
M1kNif2kKHpwluXLWH65HQJ6M+6taq0sPF59zPVyaVH9d7QPEP2ewhoExalWbv1m
n7Yc+dNo9E+MbGev9eClMGemp5tuFomK5bQg9Pd09JzKXccv5jCday6VKcHnqtfW
Wdyp8BBAAmY/WKI4jIkaC5Qa5YBJFET0BrERGs3vdmq/+G9Yna+ja5qOu2wQ1thO
c1ggC5k4QdQi1IALCQ0lQD5mFaBETtZZWlgH5Uti8emutnw=
-----END CERTIFICATE-----

@ -24,7 +24,7 @@
<repository>
<id>fdvsolution.public</id>
<name>Dynamic Jasper</name>
<url>http://archiva.fdvs.com.ar/repository/public1/</url>
<url>http://nexus.fdvs.com.ar/content/groups/public/</url>
</repository>
</repositories>
@ -229,7 +229,12 @@
<artifactId>hibernate-search</artifactId>
<version>4.4.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.2.8.Final</version>
</dependency>
<!-- ZK -->
<dependency>
<groupId>org.zkoss.zk</groupId>
@ -407,6 +412,23 @@
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.js</include>
<include>**/*.wpd</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
<dependencyManagement>
<dependencies>

@ -6,6 +6,7 @@ import info.bukova.isspst.data.NumberSeries;
import info.bukova.isspst.data.Permission;
import info.bukova.isspst.data.RequirementType;
import info.bukova.isspst.data.Role;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.data.SettingsData;
import info.bukova.isspst.data.User;
import info.bukova.isspst.reporting.Report;
@ -17,6 +18,8 @@ import info.bukova.isspst.services.munits.MUnitService;
import info.bukova.isspst.services.numberseries.NumberSeriesService;
import info.bukova.isspst.services.requirement.RequirementTypeService;
import info.bukova.isspst.services.settings.GlobalSettingsService;
import info.bukova.isspst.services.settings.SeasonException;
import info.bukova.isspst.services.settings.SeasonService;
import info.bukova.isspst.services.users.PermissionService;
import info.bukova.isspst.services.users.RoleService;
import info.bukova.isspst.services.users.UserService;
@ -29,6 +32,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
public class AppInitListener implements ServletContextListener {
@ -43,7 +47,8 @@ public class AppInitListener implements ServletContextListener {
private RequirementTypeService reqTypeService;
private GlobalSettingsService gSettingsService;
private FullTextService ftService;
private SeasonService seasonService;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
@ -64,6 +69,7 @@ public class AppInitListener implements ServletContextListener {
gSettingsService = ctx.getBean(GlobalSettingsService.class);
reqTypeService = ctx.getBean(RequirementTypeService.class);
ftService = ctx.getBean(FullTextService.class);
seasonService = ctx.getBean(SeasonService.class);
userService.grantAdmin();
this.checkDbInfo();
@ -285,29 +291,41 @@ public class AppInitListener implements ServletContextListener {
}
}
}
private void checkNumberSeriesForSeason(Season season) {
for (String modId : Constants.NUM_SERIES_PREFIX.keySet()) {
NumberSeries ns = nsService.getNumberSerieForSeason(modId, season);
if (ns == null) {
ns = new NumberSeries();
ns.setModule(modId);
ns.setPrefix(Constants.NUM_SERIES_PREFIX.get(modId));
ns.setNumber(1);
ns.setSeason(season);
nsService.add(ns);
}
}
}
private void checkNumberSeries()
{
NumberSeries ns = nsService.getNumberSerie(Constants.MOD_REQUIREMENTS);
if (ns == null)
{
ns = new NumberSeries();
ns.setModule(Constants.MOD_REQUIREMENTS);
ns.setPrefix("");
ns.setNumber(1);
nsService.add(ns);
Season season;
try {
season = seasonService.getActive();
} catch (SeasonException e) {
season = null;
}
ns = nsService.getNumberSerie(Constants.MOD_ORDER);
if (ns == null)
{
ns = new NumberSeries();
ns.setModule(Constants.MOD_ORDER);
ns.setPrefix("");
ns.setNumber(1);
nsService.add(ns);
if (season == null) {
season = new Season();
Calendar cal = Calendar.getInstance();
season.setDescription(String.valueOf(cal.get(Calendar.YEAR)));
season.setValidFrom(cal.getTime());
season.setActive(true);
seasonService.add(season);
}
for (Season s : seasonService.getAllSeasons()) {
checkNumberSeriesForSeason(s);
}
}

@ -4,6 +4,7 @@ import java.math.BigDecimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.commons.lang.StringUtils.strip;
public class BigDecimalUtils
{
@ -23,6 +24,17 @@ public class BigDecimalUtils
String valueS = value.toPlainString();
String searchS = search.toPlainString();
if (valueS.contains(".") || valueS.contains(",")) {
valueS = strip(valueS, "0");
valueS = strip(valueS, ".,");
}
if (searchS.contains(".") || searchS.contains(",")) {
searchS = strip(searchS, "0");
searchS = strip(searchS, ".,");
}
boolean result = (valueS.compareTo(searchS) == 0);
String s = "search='" + searchS + "', value='" + valueS + "', equal=" + (result ? "true" : "false");

@ -15,6 +15,7 @@ import info.bukova.isspst.services.addressbook.AdbService;
import info.bukova.isspst.services.buildings.BuildingService;
import info.bukova.isspst.services.fulltext.FullTextService;
import info.bukova.isspst.services.invoicing.InvoicingService;
import info.bukova.isspst.services.limits.LimitService;
import info.bukova.isspst.services.munits.MUnitService;
import info.bukova.isspst.services.orders.ApprovedService;
import info.bukova.isspst.services.orders.OrderService;
@ -23,6 +24,7 @@ import info.bukova.isspst.services.reqsubjects.ServiceItemService;
import info.bukova.isspst.services.requirement.RequirementService;
import info.bukova.isspst.services.requirement.RequirementTypeService;
import info.bukova.isspst.services.requirement.TripRequirementService;
import info.bukova.isspst.services.signeddocs.SignedDocumentService;
import info.bukova.isspst.services.tripbill.TripBillService;
import info.bukova.isspst.services.users.RoleService;
import info.bukova.isspst.services.users.UserService;
@ -34,7 +36,7 @@ import java.util.Map;
public class Constants {
public final static long DB_VERSION = 5;
public final static long DB_VERSION = 7;
public final static String DEF_ADMIN = "admin";
public final static String DEF_ADMIN_PASSWD = "admin";
@ -86,6 +88,8 @@ public class Constants {
public final static String MOD_ORDER = "ORDER";
public final static String MOD_INVOICING = "INVOICING";
public final static String MOD_SEARCH = "SEARCH";
public final static String MOD_SIGNEDDOCS = "SIGNEDDOCS";
public final static String MOD_LIMITS = "LIMITS";
public final static Module MODULES[] = {
new Module(MOD_USERS, "Uživatelé", UserService.class),
new Module(MOD_PERMISSIONS, "Práva", RoleService.class),
@ -103,6 +107,8 @@ public class Constants {
new Module(MOD_ORDER, "Objednávky", OrderService.class),
new Module(MOD_INVOICING, "Fakturace požadavků", InvoicingService.class),
new Module(MOD_SEARCH, "Fulltextové vyhledávání", FullTextService.class, true, false),
new Module(MOD_SIGNEDDOCS, "Podepsané dokumenty", SignedDocumentService.class, true, false),
new Module(MOD_LIMITS, "Limity komisi", LimitService.class),
};
public final static String PERM_APPROVE = "PERM_APPROVE";
@ -113,6 +119,7 @@ public class Constants {
public final static String PERM_EDIT_OWN = "PERM_EDIT_OWN";
public final static String PERM_DELETE_NEW = "PERM_DELETE_NEW";
public final static String PERM_SEARCH = "PERM_SEARCH";
public final static String PERM_PAY_BILL = "PERM_PAY_BILL";
public final static Permission SPECIAL_PERMISSIONS[] = {
new Permission(PERM_EDIT_NEW, "Upravit neschválené", MOD_REQUIREMENTS, PermissionType.GLOBAL),
@ -130,17 +137,39 @@ public class Constants {
new Permission(PERM_APPROVE, "Schválení", MOD_TRIPREQUIREMENTS, PermissionType.WORKGROUP),
new Permission(PERM_SEARCH, "Vyhledávat", MOD_SEARCH, PermissionType.GLOBAL),
new Permission(PERM_READ, "Číst", MOD_SIGNEDDOCS, PermissionType.GLOBAL),
new Permission(PERM_PAY_BILL, "Vyplacení SC", MOD_TRIPBILL, PermissionType.GLOBAL)
};
public final static String DYNAMIC_REPORT_NAME = "Tabulková sestava";
public final static ReportMapping REPORTS[] = {
new ReportMapping(MOD_ADDRESSBOOK, new Report("Adresní karty", "address")),
new ReportMapping(MOD_ADDRESSBOOK, new Report("Adresa", "address", false, true)),
new ReportMapping(MOD_TRIPBILL, new Report("Žádost", "tripRequirement", false, true)),
new ReportMapping(MOD_TRIPBILL, new Report("Vyúčtování", "tripBill", false, true, true)),
new ReportMapping(MOD_ORDER, new Report("Objednávka", "order", true, true)),
new ReportMapping(MOD_REQUIREMENTS, new Report("Požadavky", "requirements"))
new ReportMapping(MOD_ADDRESSBOOK, new Report(1, false, "Adresní karty", "address")),
new ReportMapping(MOD_ADDRESSBOOK, new Report(2, false, "Adresa", "address", false, true)),
new ReportMapping(MOD_TRIPBILL, new Report(7, true, "Žádost o SC", "tripRequirementApp", false, true, "requirement")),
new ReportMapping(MOD_TRIPBILL, new Report(4, true, "Vyúčtování", "tripBill", false, true, true)),
new ReportMapping(MOD_ORDER, new Report(5, false, "Objednávka", "order", true, true)),
new ReportMapping(MOD_REQUIREMENTS, new Report(6, false, "Požadavky", "requirements")),
new ReportMapping(MOD_TRIPREQUIREMENTS, new Report(7, true, "Žádost o SC", "tripRequirementApp", false, true)),
new ReportMapping(MOD_REQUIREMENTS, new Report(8, true, "Protokol o kontrole", "orderRequirement", false, true)),
new ReportMapping(MOD_INVOICING, new Report(9, false, "Přehled o protokolech předběžné kontroly", "requirementProtocol")),
new ReportMapping(MOD_TRIPREQUIREMENTS, new Report(10, true, "Přehled o protokolech předběžné kontroly", "tripRequirementProtocol"))
};
public final static long TRIB_BILLS_REP_ID = 100;
public final static long TRIB_BILLS_NP_REP_ID = 101;
// pokud je v agnde vic nez jedena podepisovaci sestava, musi se definovat ktera sestava nalezi jake entite
public final static Map<Class<?>, Integer> SIGN_REPORT_MAP = Collections.unmodifiableMap(new HashMap<Class<?>, Integer>() {{
put(TripBillApproval.class, 4);
put(TripRequirement.class, 7);
}});
// vychozi prefixy ciselnych rad. Pokud se prida agenda s vlastni ciselnou radou, je potreba zadefinovat vychozi prefix
public final static Map<String, String> NUM_SERIES_PREFIX = Collections.unmodifiableMap(new HashMap<String, String>() {{
put(MOD_REQUIREMENTS, "P");
put(MOD_ORDER, "O");
}});
public final static String REQTYPE_ORDER = "ORDER";
public final static String REQTYPE_BUSINESSTRIP = "BUSINESSTRIP";
@ -156,7 +185,7 @@ public class Constants {
public final static Map<Class<?>, String> URL_MAP = Collections.unmodifiableMap(new HashMap<Class<?>, String>() {{
put(Requirement.class, "/main/orders/");
put(TripRequirement.class, "/main/trips/requirements/");
put(TripBillApproval.class, "/main/trips/requirements/");
put(TripBillApproval.class, "/main/trips/bill/");
put(Order.class, "/main/orders/created/");
put(TripBill.class, "/main/trips/bill/");
}} );
@ -164,4 +193,9 @@ public class Constants {
public final static int LEN_TEXT = 255;
public final static int LEN_DESCRIPTION = 8192;
public final static int LEN_RESULT_MESSAGE = 8192;
public final static String MAIL_URL_KEYWORD = "-url-";
public final static String KEY_SIGN_DATA = "SIGN_DATA";
public final static String KEY_SIGN_GUID = "SIGN_GUID";
}

@ -1,57 +1,135 @@
package info.bukova.isspst;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.commons.lang.time.DateUtils;
public class DateTimeUtils
{
public static Date getDate(Date value)
{
if (value == null)
{
return value;
}
// Keep date - truncate time
return DateUtils.truncate(value, Calendar.DAY_OF_MONTH);
}
public static boolean isEqualByDate(Date d1, Date d2)
{
if (d1 != null && d2 != null)
{
d1 = DateTimeUtils.getDate(d1);
d2 = DateTimeUtils.getDate(d2);
boolean equals = (d1.compareTo(d2) == 0);
return equals;
}
return false;
}
public static boolean isEqualByDateForFilter(Date value, Date search)
{
if (search == null)
{
return true;
}
else if (value != null)
{
return DateTimeUtils.isEqualByDate(value, search);
}
return false;
}
public static Date getCurrDateTime()
{
return new Date();
}
public static Date getCurrDate()
{
return DateTimeUtils.getDate(DateTimeUtils.getCurrDateTime());
}
public class DateTimeUtils {
public static Date getDate(Date value) {
if (value == null) {
return value;
}
// Keep date - truncate time
return DateUtils.truncate(value, Calendar.DAY_OF_MONTH);
}
public static int getYear(Date value) {
if (value == null) {
return 0;
}
Calendar cal =Calendar.getInstance();
cal.setTime(value);
return cal.get(Calendar.YEAR);
}
public static boolean isEqualByDate(Date d1, Date d2) {
if (d1 != null && d2 != null) {
d1 = DateTimeUtils.getDate(d1);
d2 = DateTimeUtils.getDate(d2);
boolean equals = (d1.compareTo(d2) == 0);
return equals;
}
return false;
}
public static boolean isEqualByYear(Date d1, Date d2) {
if (d1 != null && d2 != null) {
int year1 = DateTimeUtils.getYear(d1);
int year2 = DateTimeUtils.getYear(d2);
boolean equals = (year1 == year2);
return equals;
}
return false;
}
public static boolean isEqualByDateForFilter(Date value, Date search) {
if (search == null) {
return true;
} else if (value != null) {
return DateTimeUtils.isEqualByDate(value, search);
}
return false;
}
public static String getFormatedDate(Date value) {
if (value == null) {
return "";
}
SimpleDateFormat sdf = new SimpleDateFormat(StringUtils.localize("DateFormat"));
String result = sdf.format(value);
return result;
}
public static String getFormatedDirDate(Date value) {
if (value == null) {
return "";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String result = sdf.format(value);
return result;
}
public static String getFormatedDirDateDDMM(Date value) {
if (value == null) {
return "";
}
SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
String result = sdf.format(value);
return result;
}
public static String getFormatedYear(Date value) {
if (value == null) {
return "";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String result = sdf.format(value);
return result;
}
public static Date getCurrDateTime() {
return new Date();
}
public static Date getCurrDate() {
return DateTimeUtils.getDate(DateTimeUtils.getCurrDateTime());
}
public static Calendar getCalendarDelta(Date value, int calendarType, int delta) {
if (value == null) {
value = DateTimeUtils.getCurrDate();
}
Calendar calendar = new GregorianCalendar();
calendar.setTime(value);
int deltaValue = calendar.get(calendarType);
calendar.set(calendarType, deltaValue + delta);
return calendar;
}
public static Calendar getCalendar(Date value) {
if (value == null) {
value = DateTimeUtils.getCurrDate();
}
Calendar calendar = new GregorianCalendar();
calendar.setTime(value);
return calendar;
}
public static Date getDateDelta(Date value, int calendarType, int delta) {
Calendar calendar = DateTimeUtils.getCalendarDelta(value, calendarType, delta);
return calendar.getTime();
}
}

@ -1,5 +1,12 @@
package info.bukova.isspst;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.services.Service;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -37,6 +44,48 @@ public class ModuleUtils {
return null;
}
public static Module getModule(DataModel entity, ServletContext sc) {
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
for (Module m : Constants.MODULES) {
Service<?> service;
try {
service = (Service<?>) ctx.getBean(m.getServiceClass());
} catch (NoSuchBeanDefinitionException e) {
String[] beans = ctx.getBeanNamesForType(m.getServiceClass());
for (String s : beans) {
service = (Service<?>) ctx.getBean(s);
if (service.getEntityClasses().contains(entity.getClass())) {
return m;
}
}
continue;
} catch (ClassCastException e) { //nestandardní moduly neřeší...
continue;
}
if (service.getEntityClasses().contains(entity.getClass())) {
return m;
}
}
return null;
}
public static Service<?> getServiceInstance(Module m, ServletContext sc) {
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
try {
return (Service<?>) ctx.getBean(m.getServiceClass());
} catch (NoSuchBeanDefinitionException e) {
String[] beans = ctx.getBeanNamesForType(m.getServiceClass());
return (Service<?>) ctx.getBean(beans[0]);
}
}
public static boolean isActive(String id) {
return getModule(id).isActive();

@ -0,0 +1,31 @@
package info.bukova.isspst;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExUtils {
public static List<String> getMatches(String input, String regEx, int group) {
List<String> list = new ArrayList<String>();
if (!StringUtils.isNullOrEmpty(input) && !StringUtils.isNullOrEmpty(regEx)) {
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(input);
int groupCount = matcher.groupCount() + 1;
if ((groupCount >= 0) && (group < groupCount)) {
while (matcher.find()) {
String item = matcher.group(group);
list.add(item);
}
}
}
return list;
}
public static List<String> getMatches(String input, String regEx) {
return RegExUtils.getMatches(input, regEx, 0);
}
}

@ -5,6 +5,7 @@ import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workgroup;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -13,16 +14,19 @@ public class SessionData implements Serializable {
/**
*
*/
private static final long serialVersionUID = -764426911263559758L;
private static final long serialVersionUID = -764426911263559759L;
private List<Workgroup> userCentres;
private List<Workgroup> userOnlyCentres;
private List<Workgroup> userWorkgroups;
private User currentUser;
private Map<Integer, List<Role>> workgroupRoles;
private boolean loginFailed;
private Map<String, Object> properties;
public SessionData() {
loginFailed = false;
properties = new HashMap<String, Object>();
}
public List<Workgroup> getUserCentres() {
@ -65,4 +69,19 @@ public class SessionData implements Serializable {
this.loginFailed = loginFailed;
}
public void setProperty(String key, Object value) {
properties.put(key, value);
}
public Object getProperty(String key) {
return properties.get(key);
}
public List<Workgroup> getUserOnlyCentres() {
return userOnlyCentres;
}
public void setUserOnlyCentres(List<Workgroup> userOnlyCentres) {
this.userOnlyCentres = userOnlyCentres;
}
}

@ -0,0 +1,25 @@
package info.bukova.isspst;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
/**
* @author Pepa Rokos
*/
public class SpringUtils {
private static WebApplicationContext webCtx(ServletContext sc) {
return WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
}
public static Object getBean(String name, ServletContext sc) {
return webCtx(sc).getBean(name);
}
public static <T> T getBean(Class<T> clazz, ServletContext sc) {
return webCtx(sc).getBean(clazz);
}
}

@ -21,7 +21,7 @@ public class TripBillAprovalUrlResolver implements EntityUrlResolver {
if (entity instanceof TripBillApproval) {
String url = Constants.URL_MAP.get(entity.getClass());
return defUrl + url + "?select=" + String.valueOf(((TripBillApproval)entity).getBill().getRequirement().getId());
return defUrl + url + "?select=" + String.valueOf(((TripBillApproval)entity).getId());
}
return defUrl + "/app";

@ -0,0 +1,10 @@
package info.bukova.isspst.dao;
import info.bukova.isspst.data.Limit;
/**
* @author Pepa Rokos
*/
public interface LimitDao extends BaseDao<Limit> {
}

@ -0,0 +1,10 @@
package info.bukova.isspst.dao;
import info.bukova.isspst.data.Season;
/**
* @author Pepa Rokos
*/
public interface SeasonDao extends BaseDao<Season> {
}

@ -0,0 +1,7 @@
package info.bukova.isspst.dao;
import info.bukova.isspst.data.SignedDocument;
public interface SignedDocumentDao extends BaseDao<SignedDocument> {
}

@ -0,0 +1,11 @@
package info.bukova.isspst.dao.jpa;
import info.bukova.isspst.dao.LimitDao;
import info.bukova.isspst.data.Limit;
/**
* @author Pepa Rokos
*/
public class LimitDaoJPA extends BaseDaoJPA<Limit> implements LimitDao {
}

@ -0,0 +1,11 @@
package info.bukova.isspst.dao.jpa;
import info.bukova.isspst.dao.SeasonDao;
import info.bukova.isspst.data.Season;
/**
* @author Pepa Rokos
*/
public class SeasonDaoJPA extends BaseDaoJPA<Season> implements SeasonDao {
}

@ -0,0 +1,9 @@
package info.bukova.isspst.dao.jpa;
import info.bukova.isspst.dao.SignedDocumentDao;
import info.bukova.isspst.data.SignedDocument;
public class SignedDocumentDaoJPA extends BaseDaoJPA<SignedDocument> implements SignedDocumentDao {
}

@ -1,6 +1,9 @@
package info.bukova.isspst.data;
import java.util.Date;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.Column;
import javax.persistence.FetchType;
@ -10,9 +13,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import java.util.Date;
@MappedSuperclass
@Indexed
@ -29,10 +30,12 @@ public abstract class BaseData implements OwnedDataModel {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="OWNED_BY_ID")
@IndexedEmbedded
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private User ownedBy;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="MODIFIED_BY_ID")
@IndexedEmbedded
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private User modifiedBy;
@Transient
private boolean valid;

@ -1,7 +1,8 @@
package info.bukova.isspst.data;
import java.math.BigDecimal;
import java.util.List;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -11,17 +12,17 @@ import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import java.math.BigDecimal;
import java.util.List;
@Entity
@Table(name = "INVOICING")
public class Invoicing extends BaseData implements Cloneable
{
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "REQUIREMENT_ID")
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
private Requirement requirement;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@ -69,6 +70,18 @@ public class Invoicing extends BaseData implements Cloneable
this.completed = completed;
}
public String getInvoiceNumbers() {
String ret = "";
for (InvoicingItem invNum : items) {
if (!ret.isEmpty()) {
ret += ", ";
}
ret += invNum.getInvoiceNumber();
}
return ret;
}
@Override
public Object clone() throws CloneNotSupportedException
{

@ -1,5 +1,8 @@
package info.bukova.isspst.data;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@ -11,6 +14,7 @@ import javax.persistence.Table;
@Entity
@Table(name = "JOBMAPPING")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class JobMapping {
@Id
@ -19,9 +23,11 @@ public class JobMapping {
private int id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "MEMBER_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Member member;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ROLE_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Role role;
public JobMapping() {

@ -0,0 +1,50 @@
package info.bukova.isspst.data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.math.BigDecimal;
/**
* @author Pepa Rokos
*/
@Entity
@Table(name = "LIMITS")
public class Limit extends BaseData implements SeasonsAware {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "WORKGROUP_ID")
private Workgroup workgroup;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SEASON_ID")
private Season season;
@Column(name = "REQ_LIMIT", precision = 15, scale = 4)
private BigDecimal limit;
public Workgroup getWorkgroup() {
return workgroup;
}
public void setWorkgroup(Workgroup workgroup) {
this.workgroup = workgroup;
}
public Season getSeason() {
return season;
}
public void setSeason(Season season) {
this.season = season;
}
public BigDecimal getLimit() {
return limit;
}
public void setLimit(BigDecimal limit) {
this.limit = limit;
}
}

@ -1,8 +1,9 @@
package info.bukova.isspst.data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -15,12 +16,13 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public abstract class Member implements DataModel {
@Id
@ -33,6 +35,7 @@ public abstract class Member implements DataModel {
@ManyToMany
@LazyCollection(LazyCollectionOption.TRUE)
@JoinTable(name="MEMBER_PARENT", joinColumns={@JoinColumn(name="MEMBER_ID")}, inverseJoinColumns={@JoinColumn(name="PARENT_ID")})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<Workgroup> parents;
@Transient
private boolean valid;

@ -2,6 +2,8 @@ package info.bukova.isspst.data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@ -17,6 +19,10 @@ public class NumberSeries extends BaseSimpleData
@Column(name = "NUMBER")
private int number;
@OneToOne
@JoinColumn(name = "SEASON_ID")
private Season season;
public String getCurrentNumber()
{
return String.format("%s%06d", this.getPrefix(), this.getNumber());
@ -51,4 +57,12 @@ public class NumberSeries extends BaseSimpleData
{
this.number = number;
}
public Season getSeason() {
return season;
}
public void setSeason(Season season) {
this.season = season;
}
}

@ -1,11 +1,13 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
@ -13,21 +15,20 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "ORDERS")
@Indexed
public class Order extends BaseData implements Cloneable
public class Order extends BaseData implements Cloneable, SeasonsAware
{
@Column(name = "NUMSER")
@ -121,6 +122,10 @@ public class Order extends BaseData implements Cloneable
@Column(name = "DELIVERED")
private boolean delivered;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SEASON_ID")
private Season season;
public Order()
{
this.items = new ArrayList<OrderItem>();
@ -288,4 +293,12 @@ public class Order extends BaseData implements Cloneable
cloned.setTotal(new BigDecimal(this.getTotal().toString()));
return cloned;
}
public Season getSeason() {
return season;
}
public void setSeason(Season season) {
this.season = season;
}
}

@ -1,6 +1,9 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -8,10 +11,9 @@ import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
@Entity
@Table(name="PERMISSION")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Permission extends BaseSimpleData implements GrantedAuthority {
/**

@ -1,9 +1,7 @@
package info.bukova.isspst.data;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -11,9 +9,10 @@ import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "REQUIREMENT")

@ -1,10 +1,14 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -16,17 +20,14 @@ import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@MappedSuperclass
@Indexed
public class RequirementBase extends BaseData implements FilterableRequirement {
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class RequirementBase extends BaseData implements FilterableRequirement, SeasonsAware {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TYPE_ID")
@ -45,9 +46,11 @@ public class RequirementBase extends BaseData implements FilterableRequirement {
private String description;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CENTRE_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Workgroup centre;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "WORKGROUP_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Workgroup workgroup;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.TRUE)
@ -56,6 +59,12 @@ public class RequirementBase extends BaseData implements FilterableRequirement {
@Column(name = "STATE")
@Enumerated(EnumType.ORDINAL)
private RequirementState state;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SEASON_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Season season;
@Column(name = "APPROVE_DATE")
private Date approveDate;
public RequirementBase() {
authorization = new ArrayList<AuthItem>();
@ -152,4 +161,19 @@ public class RequirementBase extends BaseData implements FilterableRequirement {
return authorization.get(authorization.size() - 1).getAuthDate();
}
public Season getSeason() {
return season;
}
public void setSeason(Season season) {
this.season = season;
}
public Date getApproveDate() {
return approveDate;
}
public void setApproveDate(Date approveDate) {
this.approveDate = approveDate;
}
}

@ -1,9 +1,11 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -11,13 +13,12 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.security.core.GrantedAuthority;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name="ROLE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Role extends BaseSimpleData implements GrantedAuthority, DataModel {
/**
@ -32,6 +33,7 @@ public class Role extends BaseSimpleData implements GrantedAuthority, DataModel
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name="ROLE_PERMISSION", joinColumns={@JoinColumn(name="ROLE_ID")}, inverseJoinColumns={@JoinColumn(name="PERMISSION_ID")})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<Permission> permissions;
@Column(name = "WORKGROUP")
private boolean workgroup;

@ -0,0 +1,83 @@
package info.bukova.isspst.data;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Date;
/**
* @author Pepa Rokos
*/
@Entity
@Table(name = "SEASON")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Season extends BaseData {
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "VALID_FROM")
private Date validFrom;
@Column(name = "VALID_TO")
private Date validTo;
@Column(name = "ACTIVE")
private boolean active;
public String getDescription() {
return description;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Season)) return false;
Season season = (Season) o;
if (getId() != season.getId()) return false;
if (active != season.active) return false;
if (description != null ? !description.equals(season.description) : season.description != null) return false;
if (validFrom != null ? !validFrom.equals(season.validFrom) : season.validFrom != null) return false;
if (validTo != null ? !validTo.equals(season.validTo) : season.validTo != null) return false;
return true;
}
@Override
public int hashCode() {
int result = description != null ? description.hashCode() : 0;
result = 31 * result + (validFrom != null ? validFrom.hashCode() : 0);
result = 31 * result + (validTo != null ? validTo.hashCode() : 0);
result = 31 * result + (active ? 1 : 0);
return result;
}
public void setDescription(String description) {
this.description = description;
}
public Date getValidFrom() {
return validFrom;
}
public void setValidFrom(Date validFrom) {
this.validFrom = validFrom;
}
public Date getValidTo() {
return validTo;
}
public void setValidTo(Date validTo) {
this.validTo = validTo;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}

@ -0,0 +1,8 @@
package info.bukova.isspst.data;
/**
* @author Pepa Rokos
*/
public interface SeasonsAware {
public Season getSeason();
}

@ -0,0 +1,123 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import info.bukova.isspst.Module;
import info.bukova.isspst.StringUtils;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "SIGNED_DOCUMENTS")
public class SignedDocument extends BaseData {
@Transient
private String agendaName;
@Column(name = "MODULE_NAME", length = Constants.LEN_TEXT)
private String moduleName;
@Column(name = "RECORD_ID")
private int recordId;
@Column(name = "NUMSER", length = Constants.LEN_TEXT)
private String numser;
@Column(name = "DESCRIPTION", length = Constants.LEN_DESCRIPTION)
private String description;
@Column(name = "SIGN_DATE")
private Date signDate;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "signedDocument", orphanRemoval = true)
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<SignedDocumentItem> items;
public SignedDocument() {
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public int getRecordId() {
return recordId;
}
public void setRecordId(int recordId) {
this.recordId = recordId;
}
public String getNumser() {
return numser;
}
public void setNumser(String numser) {
this.numser = numser;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getSignDate() {
return signDate;
}
public void setSignDate(Date signDate) {
this.signDate = signDate;
}
public String getAgendaName() {
if (!StringUtils.isNullOrEmpty(this.agendaName)) {
return this.agendaName;
}
if (StringUtils.isNullOrEmpty(this.moduleName)) {
return "";
}
for (Module m : Constants.MODULES) {
if (this.moduleName.equals(m.getId())) {
return m.getName();
}
}
return "";
}
public void setAgendaName(String agendaName) {
this.agendaName = agendaName;
}
public List<SignedDocumentItem> getItems() {
return items;
}
public void setItems(List<SignedDocumentItem> items) {
this.items = items;
}
public void addItem(SignedDocumentItem item) {
if (items == null) {
items = new ArrayList<SignedDocumentItem>();
}
item.setSignedDocument(this);
this.items.add(item);
}
}

@ -0,0 +1,88 @@
package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportMapping;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "SIGNED_DOCUMENTS_ITEMS")
public class SignedDocumentItem {
@Id
@Column(name = "ID")
@GeneratedValue
private int id;
@Column(name = "REPORT_ID")
private long reportId;
@Column(name = "REPORT_NAME", length = Constants.LEN_TEXT)
private String reportName;
@Column(name = "FILENAME", length = Constants.LEN_TEXT)
private String fileName;
@ManyToOne
@JoinColumn(name = "SIGNED_DOCUMENT_ID")
private SignedDocument signedDocument;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public long getReportId() {
return reportId;
}
public void setReportId(long reportId) {
this.reportId = reportId;
}
public String getReportName() {
return reportName;
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public String getActualReportName() {
for (ReportMapping rm : Constants.REPORTS) {
Report rep = rm.getReport();
if (this.reportId == rep.getReportId()) {
return rep.getName();
}
}
return reportName;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public SignedDocument getSignedDocument() {
return signedDocument;
}
public void setSignedDocument(SignedDocument signedDocument) {
this.signedDocument = signedDocument;
}
}

@ -2,36 +2,39 @@ package info.bukova.isspst.data;
import info.bukova.isspst.Constants;
import info.bukova.isspst.storage.EntityWithAttachment;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "TRIP_BILL")
@Indexed
public class TripBill extends BaseData implements EntityWithAttachment {
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class TripBill extends BaseData implements EntityWithAttachment, SeasonsAware {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "REQUIREMENT_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private TripRequirement requirement;
@Column(name = "RESULT_MESSAGE_DATE")
private Date resultMessageDate;
@ -62,11 +65,19 @@ public class TripBill extends BaseData implements EntityWithAttachment {
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<FileMetainfo> attachedFiles;
@OneToOne(fetch = FetchType.EAGER)
@OneToOne(fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "APPROVAL_ID")
private TripBillApproval approval;
@Column(name = "SAVED")
private Boolean saved;
private Boolean saved; // Nastaveno na true, pokud uživatel udělá změnu- nepřenáší se pak částky od žadatele
@Column(name = "PAID")
private Boolean paid;
@Column(name = "PAID_DATE")
private Date paidDate;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SEASON_ID")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Season season;
public TripBill() {
billItems = new ArrayList<TripBillItem>();
@ -188,4 +199,29 @@ public class TripBill extends BaseData implements EntityWithAttachment {
public void setSaved(Boolean saved) {
this.saved = saved;
}
public Boolean getPaid() {
return paid;
}
public void setPaid(Boolean paid) {
this.paid = paid;
}
public Date getPaidDate() {
return paidDate;
}
public void setPaidDate(Date paidDate) {
this.paidDate = paidDate;
}
@Override
public Season getSeason() {
return season;
}
public void setSeason(Season season) {
this.season = season;
}
}

@ -5,6 +5,8 @@ import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.Date;
/**
* @author Pepa Rokos
@ -17,6 +19,26 @@ public class TripBillApproval extends RequirementBase {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TRIPBILL_ID")
private TripBill bill;
@Transient
private boolean billForPassenger;
@Transient
private Date tripDate;
public boolean isBillForPassenger() {
return billForPassenger;
}
public void setBillForPassenger(boolean billForPassenger) {
this.billForPassenger = billForPassenger;
}
public Date getTripDate() {
return tripDate;
}
public void setTripDate(Date tripDate) {
this.tripDate = tripDate;
}
@Override
public String getNumser() {

@ -1,11 +1,13 @@
package info.bukova.isspst.data;
import info.bukova.isspst.storage.EntityWithAttachment;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -16,14 +18,10 @@ import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "TRIPREQUIREMENT")

@ -1,9 +1,13 @@
package info.bukova.isspst.data;
import info.bukova.isspst.StringUtils;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.Column;
import javax.persistence.Embedded;
@ -13,16 +17,13 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name="USER")
@Indexed
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User extends Member implements UserDetails, DataModel {
/**
@ -50,6 +51,7 @@ public class User extends Member implements UserDetails, DataModel {
private boolean notify;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="USER_ROLE", joinColumns={@JoinColumn(name="USER_ID")}, inverseJoinColumns={@JoinColumn(name="ROLE_ID")})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<Role> authorities;
@Column(name="SETTINGS", length=1048576)
private String settings;

@ -1,15 +1,14 @@
package info.bukova.isspst.data;
import java.math.BigDecimal;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import java.math.BigDecimal;
@Entity
@Table(name = "WORKFLOW")
@ -24,7 +23,9 @@ public class Workflow extends BaseData {
@Column(name = "WORDER")
private Integer wOrder;
@Column(name = "WLIMIT", precision=15, scale=4)
private BigDecimal limit;
private BigDecimal limit;
@Column(name = "SIGNATURE")
private Boolean signature;
public Boolean getCentre() {
return centre;
@ -68,4 +69,11 @@ public class Workflow extends BaseData {
this.limit = limit;
}
public Boolean getSignature() {
return signature;
}
public void setSignature(Boolean signature) {
this.signature = signature;
}
}

@ -1,11 +1,10 @@
package info.bukova.isspst.data;
import info.bukova.isspst.StringUtils;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@ -17,12 +16,14 @@ import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "WORKGROUP")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Workgroup extends Member implements OwnedDataModel, Serializable {
/**
@ -37,6 +38,7 @@ public class Workgroup extends Member implements OwnedDataModel, Serializable {
@ManyToMany(cascade = {CascadeType.ALL})
@LazyCollection(LazyCollectionOption.TRUE)
@JoinTable(name="WORKGROUP_MEMBER", joinColumns={@JoinColumn(name="WORKGROUP_ID")}, inverseJoinColumns={@JoinColumn(name="JOBMAPPING_ID")})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<JobMapping> members;
@Column(name = "CENTRE")
private boolean centre;

@ -1,5 +1,6 @@
package info.bukova.isspst.filters;
import info.bukova.isspst.BigDecimalUtils;
import info.bukova.isspst.BooleanUtils;
import info.bukova.isspst.DateTimeUtils;
import info.bukova.isspst.StringUtils;
@ -48,7 +49,8 @@ public class RequirementFilter implements Filter<Requirement>
boolean foundDeliveryDate = DateTimeUtils.isEqualByDateForFilter(item.getDeliveryDate(), condition.getDeliveryDate());
boolean foundUser = User.isEqualByUserForFilter(item.getOwnedBy(), condition.getOwnedBy());
boolean foundProject = BooleanUtils.isEqualByBooleanValue(item.getProject(), condition.getProject());
return (foundNumser && foundReqDate && foundCenter && foundDescription && foundDeliveryDate && foundUser && foundProject);
boolean foundSumTotal = BigDecimalUtils.isEqualByDecimalForFilter(item.getSumTotal(), condition.getSumTotal());
return (foundNumser && foundReqDate && foundCenter && foundDescription && foundDeliveryDate && foundUser && foundProject && foundSumTotal);
}
@Factory

@ -0,0 +1,64 @@
package info.bukova.isspst.filters;
import info.bukova.isspst.DateTimeUtils;
import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.SignedDocument;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class SignedDocumentFilter implements Filter<SignedDocument>
{
private SignedDocument condition;
public SignedDocumentFilter(SignedDocument cond)
{
this.condition = cond;
}
private static class SignedDocumentMatcher extends TypeSafeMatcher<SignedDocument>
{
private SignedDocument condition;
public SignedDocumentMatcher(SignedDocument cond)
{
this.condition = cond;
}
@Override
public void describeTo(Description desc)
{
desc.appendText("SignedDocument matches");
}
@Override
public boolean matchesSafely(SignedDocument item)
{
boolean foundAgendaName = StringUtils.isEqualForFilter(item.getAgendaName(), condition.getAgendaName());
boolean foundNumSer = StringUtils.isEqualForFilter(item.getNumser(), condition.getNumser());
boolean foundDescription = StringUtils.isEqualForFilter(item.getDescription(), condition.getDescription());
boolean foundSignDate = DateTimeUtils.isEqualByDateForFilter(item.getSignDate(), condition.getSignDate());
return (foundAgendaName && foundNumSer && foundDescription && foundSignDate);
}
@Factory
public static Matcher<SignedDocument> matchBuilding(SignedDocument item)
{
return new SignedDocumentMatcher(item);
}
}
@Override
public SignedDocumentMatcher matcher()
{
return new SignedDocumentMatcher(condition);
}
@Override
public String queryString()
{
return "";
}
}

@ -0,0 +1,82 @@
package info.bukova.isspst.filters;
import info.bukova.isspst.BooleanUtils;
import info.bukova.isspst.DateTimeUtils;
import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.TripBillApproval;
import info.bukova.isspst.data.User;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class TripBillApprovalFilter implements Filter<TripBillApproval>
{
private TripBillApproval condition;
public TripBillApprovalFilter(TripBillApproval cond)
{
this.condition = cond;
}
private static class TripBillApprovalMatcher extends TypeSafeMatcher<TripBillApproval>
{
private TripBillApproval condition;
public TripBillApprovalMatcher(TripBillApproval cond)
{
this.condition = cond;
}
@Override
public void describeTo(Description desc)
{
desc.appendText("requirement matches");
}
@Override
public boolean matchesSafely(TripBillApproval item)
{
if (item.getBill() == null) {
return false;
}
boolean foundNumser = StringUtils.isEqualForFilter(item.getNumser(), condition.getNumser());
boolean foundReqDate = DateTimeUtils.isEqualByDateForFilter(item.getBill().getRequirement().getReqDate(), condition.getBill().getRequirement().getReqDate());
boolean foundDescription = StringUtils.isEqualForFilter(item.getDescription(), condition.getDescription());
boolean foundFrom = StringUtils.isEqualForFilter(item.getBill().getRequirement().getFrom(), condition.getBill().getRequirement().getFrom());
boolean foundTo = StringUtils.isEqualForFilter(item.getBill().getRequirement().getTo(), condition.getBill().getRequirement().getTo());
boolean foundWorkgroup = (condition.getWorkgroup() == null ||(item.getWorkgroup() != null && item.getWorkgroup().equals(condition.getWorkgroup())));
boolean foundCentre = (condition.getCentre() == null || (item.getCentre() != null && item.getCentre().equals(condition.getCentre())));
boolean foundOwner = User.isEqualByUserForFilter(item.getBill().getOwnedBy(), condition.getBill().getOwnedBy());
boolean foundPaid = BooleanUtils.isEqualByBooleanValue(item.getBill().getPaid(), condition.getBill().getPaid());
boolean foundPaidDate = DateTimeUtils.isEqualByDateForFilter(item.getBill().getPaidDate(), condition.getBill().getPaidDate());
boolean foundPassenger = (item.getBill().getOwnedBy() != item.getBill().getRequirement().getOwnedBy()) == condition.isBillForPassenger();
boolean foundApproveDate = DateTimeUtils.isEqualByDateForFilter(item.getApproveDate(), condition.getApproveDate());
boolean foundTripDate = DateTimeUtils.isEqualByDateForFilter(item.getBill().getRequirement().getTripDate(), condition.getTripDate());
return foundNumser && foundReqDate && foundDescription && foundFrom && foundTo && foundWorkgroup && foundCentre && foundOwner && foundPaid
&& foundPaidDate && foundPassenger && foundApproveDate && foundTripDate;
}
@Factory
public static Matcher<TripBillApproval> matchTripRequirement(TripBillApproval building)
{
return new TripBillApprovalMatcher(building);
}
}
@Override
public TripBillApprovalMatcher matcher()
{
return new TripBillApprovalMatcher(condition);
}
@Override
public String queryString()
{
return "";
}
}

@ -1,5 +1,6 @@
package info.bukova.isspst.mail;
import info.bukova.isspst.Constants;
import info.bukova.isspst.EntityUrlResolver;
import info.bukova.isspst.UrlResolverHolder;
@ -57,7 +58,7 @@ public class EntityMessageBuilder implements MessageBuilder {
for (String p : properties) {
try {
if (p.equals("-url-")) {
if (p.equals(Constants.MAIL_URL_KEYWORD)) {
ret = ret.replaceAll("\\[" + p + "\\]", getUrl(data));
} else {
ret = ret.replaceAll("\\[" + p + "\\]", BeanUtils.getProperty(data, p));

@ -12,8 +12,10 @@ import info.bukova.isspst.services.settings.GlobalSettingsService;
import info.bukova.isspst.services.tripbill.TripBillApprovalService;
import info.bukova.isspst.services.users.UserService;
import info.bukova.isspst.storage.FileStorage;
import net.sf.jasperreports.engine.JRParameter;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@ -31,6 +33,8 @@ public class ParamFiller {
private GlobalSettingsService settingService;
@Autowired
private TripBillApprovalService tripBillApprovalService;
@Autowired
private HttpServletRequest req;
public void fill() {
if (definition.getDataSet() == null || definition.getDataSet().isEmpty()) {
@ -74,7 +78,7 @@ public class ParamFiller {
definition.setParam("P_PREV_APPROVER_SIGNATURE", storage.serverPath(prevApproverSettings.getSignatureFile()));
}
AuthItem lastAuth = tb.getApproval().getAuthorization().get(tb.getRequirement().getAuthorization().size() - 1);
AuthItem lastAuth = tb.getApproval().getAuthorization().get(tb.getApproval().getAuthorization().size() - 1);
definition.setParam("P_APPROVE_DATE", lastAuth.getAuthDate());
User u = lastAuth.getApprover();
@ -95,6 +99,7 @@ public class ParamFiller {
}
definition.setParam("P_LOGO", storage.serverPath(settingService.getSettings().getLogoFile()));
definition.setParam(JRParameter.REPORT_LOCALE, req.getLocale());
Address mainAddress = settingService.getSettings().getMainAddress();

@ -1,18 +1,21 @@
package info.bukova.isspst.reporting;
import java.io.File;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.bukova.isspst.SpringUtils;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.services.signeddocs.SignedDocumentService;
import info.bukova.isspst.storage.ReportFileStorage;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import java.io.File;
@SuppressWarnings("deprecation")
public class PredefinedGenerator implements Generator {
@ -20,7 +23,7 @@ public class PredefinedGenerator implements Generator {
private ReportDefinition definition;
private ServletContext ctx;
private final static Logger logger = LoggerFactory.getLogger(PredefinedGenerator.class);
public PredefinedGenerator(ReportDefinition definition, ServletContext ctx) {
this.definition = definition;
this.ctx = ctx;
@ -29,7 +32,12 @@ public class PredefinedGenerator implements Generator {
@Override
public byte[] generate() {
byte[] bytes = null;
SignedDocumentItem signedItem = getSignedDocument();
if (signedItem != null) {
return fromStorage(signedItem);
}
try {
JasperReport report = (JasperReport) JRLoader.loadObject(getReportFile());
JRProperties.setProperty("net.sf.jasperreports.default.pdf.encoding", "Cp1250");
@ -43,6 +51,18 @@ public class PredefinedGenerator implements Generator {
return bytes;
}
private byte[] fromStorage(SignedDocumentItem sdItem) {
ReportFileStorage reportStorage = SpringUtils.getBean(ReportFileStorage.class, ctx);
return reportStorage.fileData(sdItem);
}
private SignedDocumentItem getSignedDocument() {
SignedDocumentService sdService = SpringUtils.getBean(SignedDocumentService.class, ctx);
SignedDocumentItem sdItem = sdService.getItem((DataModel) definition.getDataSet().get(0), definition.getReport().getReportId());
return sdItem;
}
protected File getReportFile() {
return new File(ctx.getRealPath("WEB-INF/reports") + "/" + definition.getReport().getJasperFile() + ".jasper");

@ -4,60 +4,80 @@ package info.bukova.isspst.reporting;
public class Report {
private ReportType type;
private long reportId;
private boolean signable;
private String name;
private String jasperFile;
private boolean hasSettings;
private boolean singleRecord;
private boolean hasCondition;
private String property;
public Report() {
this.reportId = 0;
this.signable = false;
hasSettings = false;
singleRecord = false;
hasCondition = false;
}
/**
* @param reportId
* @param signable
* @param name
* @param jasperFile
*/
public Report(String name, String jasperFile) {
public Report(long reportId, boolean signable, String name, String jasperFile) {
this();
this.type = ReportType.DEFINED;
this.reportId = reportId;
this.signable = signable;
this.name = name;
this.jasperFile = jasperFile;
}
/**
* @param reportId
* @param signable
* @param name
* @param jasperFile
* @param hasSettings
*/
public Report(String name, String jasperFile, boolean hasSettings) {
this(name, jasperFile);
public Report(long reportId, boolean signable, String name, String jasperFile, boolean hasSettings) {
this(reportId, signable, name, jasperFile);
this.hasSettings = hasSettings;
}
/**
* @param reportId
* @param signable
* @param name
* @param jasperFile
* @param hasSettings
* @param singleRecord
*/
public Report(String name, String jasperFile, boolean hasSettings, boolean singleRecord) {
this(name, jasperFile, hasSettings);
public Report(long reportId, boolean signable, String name, String jasperFile, boolean hasSettings, boolean singleRecord) {
this(reportId, signable, name, jasperFile, hasSettings);
this.singleRecord = singleRecord;
}
public Report(long reportId, boolean signable, String name, String jasperFile, boolean hasSettings, boolean singleRecord, String property) {
this(reportId, signable, name, jasperFile, hasSettings, singleRecord);
this.property = property;
}
/**
*
*
* @param reportId
* @param signable
* @param name
* @param jasperFile
* @param hasSettings
* @param singleRecord
* @param hasCondition
*/
public Report(String name, String jasperFile, boolean hasSettings, boolean singleRecord, boolean hasCondition) {
this(name, jasperFile, hasSettings, singleRecord);
public Report(long reportId, boolean signable, String name, String jasperFile, boolean hasSettings, boolean singleRecord, boolean hasCondition) {
this(reportId, signable, name, jasperFile, hasSettings, singleRecord);
this.hasCondition = hasCondition;
}
@ -108,4 +128,28 @@ public class Report {
public void setHasCondition(boolean hasCondition) {
this.hasCondition = hasCondition;
}
public long getReportId() {
return reportId;
}
public void setReportId(long reportId) {
this.reportId = reportId;
}
public boolean isSignable() {
return signable;
}
public void setSignable(boolean signable) {
this.signable = signable;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
}

@ -1,17 +1,17 @@
package info.bukova.isspst.reporting;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import info.bukova.isspst.storage.ReportFileStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
@Controller
public class ReportController {
@ -21,6 +21,8 @@ public class ReportController {
private GeneratorFactory factory;
@Autowired
private ParamFiller paramFiller;
@Autowired
private ReportFileStorage reportFileStorage;
private static final String ERROR_MESSAGE = "<html><body><b>Generator returned no data!</b><br/>%s</body></html>";
private final static Logger logger = LoggerFactory.getLogger(ReportController.class);
@ -46,13 +48,20 @@ public class ReportController {
try {
os = response.getOutputStream();
if (reportDefinition.getReport() == null || reportDefinition.getDataSet() == null) {
if ((reportDefinition.getReport() == null || reportDefinition.getDataSet() == null) && reportDefinition.getSignedDocItem() == null) {
throw new ReportException("Definition is null");
}
paramFiller.fill();
Generator gen = factory.createGenerator(reportDefinition);
byte[] data = gen.generate();
byte[] data;
if (reportDefinition.getSignedDocItem() == null) {
paramFiller.fill();
Generator gen = factory.createGenerator(reportDefinition);
data = gen.generate();
} else {
data = reportFileStorage.fileData(reportDefinition.getSignedDocItem());
}
response.setContentType(contentType);
response.setContentLength(data.length);
@ -64,6 +73,9 @@ public class ReportController {
} catch (ReportException e) {
logger.error("Report generation error: " + e.getMessage());
writeError(os, e);
} catch (Exception e) {
logger.error("Report generation error: " + e.getMessage());
writeError(os, e);
} finally {
if (os != null) {
try {

@ -1,5 +1,6 @@
package info.bukova.isspst.reporting;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.services.Service;
import java.io.Serializable;
@ -20,6 +21,7 @@ public class ReportDefinition implements Serializable {
private List<String> fieldsToPrint;
private String reportTitle;
private Service<Object> service;
private SignedDocumentItem signedDocItem;
public ReportDefinition() {
params = new HashMap<String, Object>();
@ -92,6 +94,7 @@ public class ReportDefinition implements Serializable {
reportTitle = "";
service = null;
params.clear();
signedDocItem = null;
}
public String getReportTitle() {
@ -110,4 +113,11 @@ public class ReportDefinition implements Serializable {
this.service = service;
}
public SignedDocumentItem getSignedDocItem() {
return signedDocItem;
}
public void setSignedDocItem(SignedDocumentItem signedDocItem) {
this.signedDocItem = signedDocItem;
}
}

@ -0,0 +1,68 @@
package info.bukova.isspst.reporting;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfFormField;
import com.lowagie.text.pdf.PdfName;
import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRPropertiesMap;
import net.sf.jasperreports.engine.export.GenericElementHandler;
import net.sf.jasperreports.engine.export.GenericElementHandlerBundle;
import net.sf.jasperreports.engine.export.GenericElementPdfHandler;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterContext;
import net.sf.jasperreports.extensions.ExtensionsRegistry;
import net.sf.jasperreports.extensions.ExtensionsRegistryFactory;
import net.sf.jasperreports.extensions.SingletonExtensionRegistry;
/**
* @author Pepa Rokos
*/
public class SignaturePdfHandler implements GenericElementPdfHandler, GenericElementHandlerBundle, ExtensionsRegistryFactory {
@Override
public ExtensionsRegistry createRegistry(String registryId, JRPropertiesMap properties) {
return new SingletonExtensionRegistry<GenericElementHandlerBundle>(GenericElementHandlerBundle.class, this);
}
@Override
public void exportElement(JRPdfExporterContext exporterContext, JRGenericPrintElement element) {
//PdfFormField field = PdfFormField.createSignature(exporterContext.getPdfWriter());
PdfFormField field = PdfFormField.createTextField(exporterContext.getPdfWriter(), true, false, 255);
Object param = element.getParameterValue("index");
String index = param != null ? String.valueOf(param) : null;
if (index != null) {
field.setFieldName("signature-" + index);
} else {
field.setFieldName("signature");
}
field.put(PdfName.V, exporterContext.getPdfWriter().getPdfIndirectReference());
field.setFieldFlags(PdfFormField.FF_READ_ONLY);
field.setWidget(new Rectangle(element.getX(),
exporterContext.getExportedReport().getPageHeight() - element.getY(),
element.getX() + element.getWidth(),
exporterContext.getExportedReport().getPageHeight() - element.getY() - element.getHeight()), PdfName.HIGHLIGHT);
exporterContext.getPdfWriter().addAnnotation(field);
}
@Override
public boolean toExport(JRGenericPrintElement element) {
return true;
}
@Override
public String getNamespace() {
return "urn:sig:sig";
}
@Override
public GenericElementHandler getHandler(String elementName, String exporterKey) {
if (elementName.equals("signature") && exporterKey.equals(JRPdfExporter.PDF_EXPORTER_KEY)) {
return this;
}
return null;
}
}

@ -0,0 +1,306 @@
package info.bukova.isspst.security;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
import org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.InitialLdapContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AdAuthenticationProvider extends AbstractLdapAuthenticationProvider{
private static final Pattern SUB_ERROR_CODE = Pattern.compile(".*data\\s([0-9a-f]{3,4}).*");
// Error codes
private static final int USERNAME_NOT_FOUND = 0x525;
private static final int INVALID_PASSWORD = 0x52e;
private static final int NOT_PERMITTED = 0x530;
private static final int PASSWORD_EXPIRED = 0x532;
private static final int ACCOUNT_DISABLED = 0x533;
private static final int ACCOUNT_EXPIRED = 0x701;
private static final int PASSWORD_NEEDS_RESET = 0x773;
private static final int ACCOUNT_LOCKED = 0x775;
private final String domain;
private final String rootDn;
private final String url;
private final String upnSuffix;
private boolean convertSubErrorCodesToExceptions;
// Only used to allow tests to substitute a mock LdapContext
ContextFactory contextFactory = new ContextFactory();
/**
* @param domain the domain for which authentication should take place
*/
// public ActiveDirectoryLdapAuthenticationProvider(String domain) {
// this (domain, null);
// }
/**
* @param domain the domain name (may be null or empty)
* @param url an LDAP url (or multiple URLs)
*/
public AdAuthenticationProvider(String domain, String upnSuffix, String url) {
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
//this.url = StringUtils.hasText(url) ? url : null;
this.url = url;
this.upnSuffix = upnSuffix;
rootDn = this.domain == null ? null : rootDnFromDomain(this.domain);
}
@Override
protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth) {
String username = auth.getName();
String password = (String)auth.getCredentials();
DirContext ctx = bindAsUser(username, password);
try {
return searchForUser(ctx, username);
} catch (NamingException e) {
logger.error("Failed to locate directory entry for authenticated user: " + username, e);
throw badCredentials();
} finally {
LdapUtils.closeContext(ctx);
}
}
/**
* Creates the user authority list from the values of the {@code memberOf} attribute obtained from the user's
* Active Directory entry.
*/
@Override
protected Collection<? extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData, String username, String password) {
String[] groups = userData.getStringAttributes("memberOf");
if (groups == null) {
logger.debug("No values for 'memberOf' attribute.");
return AuthorityUtils.NO_AUTHORITIES;
}
if (logger.isDebugEnabled()) {
logger.debug("'memberOf' attribute values: " + Arrays.asList(groups));
}
ArrayList<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(groups.length);
for (String group : groups) {
authorities.add(new SimpleGrantedAuthority(new DistinguishedName(group).removeLast().getValue()));
}
return authorities;
}
private DirContext bindAsUser(String username, String password) {
// TODO. add DNS lookup based on domain
final String bindUrl = url;
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
String bindPrincipal = createBindPrincipal(username);
env.put(Context.SECURITY_PRINCIPAL, bindPrincipal);
env.put(Context.PROVIDER_URL, bindUrl);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
try {
return contextFactory.createContext(env);
} catch (NamingException e) {
if ((e instanceof AuthenticationException) || (e instanceof OperationNotSupportedException)) {
handleBindException(bindPrincipal, e);
throw badCredentials();
} else {
throw LdapUtils.convertLdapException(e);
}
}
}
void handleBindException(String bindPrincipal, NamingException exception) {
if (logger.isDebugEnabled()) {
logger.debug("Authentication for " + bindPrincipal + " failed:" + exception);
}
int subErrorCode = parseSubErrorCode(exception.getMessage());
if (subErrorCode > 0) {
logger.info("Active Directory authentication failed: " + subCodeToLogMessage(subErrorCode));
if (convertSubErrorCodesToExceptions) {
raiseExceptionForErrorCode(subErrorCode);
}
} else {
logger.debug("Failed to locate AD-specific sub-error code in message");
}
}
int parseSubErrorCode(String message) {
Matcher m = SUB_ERROR_CODE.matcher(message);
if (m.matches()) {
return Integer.parseInt(m.group(1), 16);
}
return -1;
}
void raiseExceptionForErrorCode(int code) {
switch (code) {
case PASSWORD_EXPIRED:
throw new CredentialsExpiredException(messages.getMessage("LdapAuthenticationProvider.credentialsExpired",
"User credentials have expired"));
case ACCOUNT_DISABLED:
throw new DisabledException(messages.getMessage("LdapAuthenticationProvider.disabled",
"User is disabled"));
case ACCOUNT_EXPIRED:
throw new AccountExpiredException(messages.getMessage("LdapAuthenticationProvider.expired",
"User account has expired"));
case ACCOUNT_LOCKED:
throw new LockedException(messages.getMessage("LdapAuthenticationProvider.locked",
"User account is locked"));
}
}
String subCodeToLogMessage(int code) {
switch (code) {
case USERNAME_NOT_FOUND:
return "User was not found in directory";
case INVALID_PASSWORD:
return "Supplied password was invalid";
case NOT_PERMITTED:
return "User not permitted to logon at this time";
case PASSWORD_EXPIRED:
return "Password has expired";
case ACCOUNT_DISABLED:
return "Account is disabled";
case ACCOUNT_EXPIRED:
return "Account expired";
case PASSWORD_NEEDS_RESET:
return "User must reset password";
case ACCOUNT_LOCKED:
return "Account locked";
}
return "Unknown (error code " + Integer.toHexString(code) +")";
}
private BadCredentialsException badCredentials() {
return new BadCredentialsException(messages.getMessage(
"LdapAuthenticationProvider.badCredentials", "Bad credentials"));
}
private DirContextOperations searchForUser(DirContext ctx, String username) throws NamingException {
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
final String bindPrincipal = createBindPrincipal(username);
final String searchDn = createSearchDn(username);
String searchRoot = rootDn != null ? rootDn : searchRootFromPrincipal(bindPrincipal);
DirContextOperations ctxOp;
try {
ctxOp = SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, searchCtls, searchRoot, searchFilter,
new Object[]{searchDn});
if (ctxOp != null) {
return ctxOp;
}
} catch (Exception e) {
logger.warn("UPN " + searchDn + " not found. Falling back to search with domain UPN suffix.");
}
return SpringSecurityLdapTemplate.searchForSingleEntryInternal(ctx, searchCtls, searchRoot, searchFilter,
new Object[]{bindPrincipal});
}
private String searchRootFromPrincipal(String bindPrincipal) {
int atChar = bindPrincipal.lastIndexOf('@');
if (atChar < 0) {
logger.debug("User principal '" + bindPrincipal + "' does not contain the domain, and no domain has been configured");
throw badCredentials();
}
return rootDnFromDomain(bindPrincipal.substring(atChar+ 1, bindPrincipal.length()));
}
private String rootDnFromDomain(String domain) {
String[] tokens = StringUtils.tokenizeToStringArray(domain, ".");
StringBuilder root = new StringBuilder();
for (String token : tokens) {
if (root.length() > 0) {
root.append(',');
}
root.append("dc=").append(token);
}
return root.toString();
}
String createBindPrincipal(String username) {
if (domain == null || username.toLowerCase().endsWith(domain)) {
return username;
}
return username + "@" + domain;
}
String createSearchDn(String username) {
if (upnSuffix == null) {
return createBindPrincipal(username);
}
return username + "@" + upnSuffix;
}
/**
* By default, a failed authentication (LDAP error 49) will result in a {@code BadCredentialsException}.
* <p>
* If this property is set to {@code true}, the exception message from a failed bind attempt will be parsed
* for the AD-specific error code and a {@link CredentialsExpiredException}, {@link DisabledException},
* {@link AccountExpiredException} or {@link LockedException} will be thrown for the corresponding codes. All
* other codes will result in the default {@code BadCredentialsException}.
*
* @param convertSubErrorCodesToExceptions {@code true} to raise an exception based on the AD error code.
*/
public void setConvertSubErrorCodesToExceptions(boolean convertSubErrorCodesToExceptions) {
this.convertSubErrorCodesToExceptions = convertSubErrorCodesToExceptions;
}
static class ContextFactory {
DirContext createContext(Hashtable<?,?> env) throws NamingException {
return new InitialLdapContext(env, null);
}
}
}

@ -5,9 +5,6 @@ import info.bukova.isspst.data.User;
import info.bukova.isspst.services.users.LdapUserImporter;
import info.bukova.isspst.services.users.RoleService;
import info.bukova.isspst.services.users.UserService;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextOperations;
@ -15,6 +12,8 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
import java.util.Collection;
public class AuthPopulator implements LdapAuthoritiesPopulator {
private UserService userService;
@ -30,7 +29,8 @@ public class AuthPopulator implements LdapAuthoritiesPopulator {
public Collection<? extends GrantedAuthority> getGrantedAuthorities(
DirContextOperations userData, String login) {
User user = null;
User user;
try {
user = (User) userService.loadUserByUsername(login);
} catch (UsernameNotFoundException e) {

@ -7,16 +7,6 @@ import info.bukova.isspst.data.UserSettingsData;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.users.UserService;
import info.bukova.isspst.services.workgroups.WorkgroupService;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,6 +14,14 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Autowired
@ -45,6 +43,7 @@ public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessH
logger.info("User " + u.getUsername() + " logged in");
sessionData.setUserCentres(workgroupService.getUserCentres((User) auth.getPrincipal()));
sessionData.setUserOnlyCentres(workgroupService.getUserCentres((User) auth.getPrincipal(), true));
sessionData.setUserWorkgroups(workgroupService.getUserWorkgroups((User) auth.getPrincipal()));
workgroupService.loadParents(u);
sessionData.setCurrentUser(u);

@ -14,6 +14,7 @@ import info.bukova.isspst.storage.DocumentFileStorage;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.GenericTypeResolver;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
@ -22,6 +23,7 @@ import javax.validation.Validator;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@ -36,11 +38,25 @@ public abstract class AbstractService<T extends DataModel> implements Service<T>
@Autowired
protected SessionData sessionData;
@Autowired
protected HqlDataFilter hqlFilter;
@Autowired
protected QueryDao queryDao;
private DocumentFileStorage documentFileStorage;
private NumberSeriesService numberSeriesService;
private Class<T> entityClass;
public AbstractService() {
entityClass = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), AbstractService.class);
}
@Override
public List<Class<?>> getEntityClasses() {
List<Class<?>> classes = new ArrayList<Class<?>>();
classes.add(entityClass);
return classes;
}
public void setDocumentFileStorage(DocumentFileStorage storage) {
this.documentFileStorage = storage;
@ -74,6 +90,50 @@ public abstract class AbstractService<T extends DataModel> implements Service<T>
}
}
protected Query filterQuery(Query q) {
return filterQuery(q, null);
}
protected Query filterQuery(Query q, HqlDataFilter aditFilter) {
HqlDataFilter f = hqlFilter;
try {
if (((f.getWhere() == null || f.getWhere().isEmpty())
&& (f.getOrderBy() == null || f.getOrderBy().isEmpty()))
&& ((aditFilter.getWhere() == null || aditFilter.getWhere().isEmpty())
&& (aditFilter.getOrderBy() == null || aditFilter.getOrderBy().isEmpty()))) {
return q;
}
} catch (Exception e) {
f = new HqlDataFilter(); // pri volani mimo web request filtr z requestu neresime
}
boolean isAplicable = false;
if (f.getDataClass() != null) {
for (Class<?> clazz : getEntityClasses()) {
if (f.getDataClass().isAssignableFrom(clazz)) {
isAplicable = true;
}
}
}
String hql;
if (isAplicable) {
hql = HqlUtils.buildHql(q.getQueryString(), f);
} else {
hql = q.getQueryString();
}
hql = HqlUtils.addOrderBy(HqlUtils.addAndWhere(hql, aditFilter), aditFilter);
Query newQuery = dao.getQuery(hql);
if (isAplicable) {
HqlUtils.addParameters(newQuery, f);
}
HqlUtils.addParameters(newQuery, aditFilter);
return newQuery;
}
@Override
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
public final T create() {
@ -185,8 +245,10 @@ public abstract class AbstractService<T extends DataModel> implements Service<T>
if (getModule() != null && !getModule().isActive()) {
throw new ModuleNotActiveException();
}
Query q = dao.getQuery("from " + dao.getEntityName());
return dao.getAll();
return filterQuery(q).list();
}
@Override

@ -0,0 +1,87 @@
package info.bukova.isspst.services;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author Pepa Rokos
*/
public class HqlDataFilter {
private String where;
private String orderBy;
private Map<String, Object> params;
private Class<?> dataClass;
public HqlDataFilter() {
params = new HashMap<String, Object>();
}
public HqlDataFilter(String where) {
this();
this.where = where;
}
public HqlDataFilter(String where, String orderBy) {
this(where);
this.orderBy = orderBy;
}
public String getWhere() {
return where;
}
public void setWhere(String where) {
this.where = where;
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public void setParam(String key, Object value) {
params.put(key, value);
}
public Object getParam(String key) {
return params.get(key);
}
public Set<String> getParamKeys() {
return params.keySet();
}
public void andFilter(String filter) {
if (where == null || where.isEmpty()) {
where = filter;
} else {
where += " and (" + filter + ")";
}
}
public void orFilter(String filter) {
if (where == null ||where.isEmpty()) {
where = filter;
} else {
where += " or (" + filter + ")";
}
}
public void reset() {
where = "";
orderBy = "";
params.clear();
}
public Class<?> getDataClass() {
return dataClass;
}
public void setDataClass(Class<?> dataClass) {
this.dataClass = dataClass;
}
}

@ -0,0 +1,90 @@
package info.bukova.isspst.services;
import org.hibernate.Query;
import java.util.Collection;
/**
* @author Pepa Rokos
*/
public class HqlUtils {
public static String buildHql(String select, HqlDataFilter filter) {
if (select.toLowerCase().contains("where")
|| select.toLowerCase().contains("order by")) {
throw new IsspstException("Use add*() methods instead.");
}
String hql = addWhere(select, filter, "");
return addOrderBy(hql, filter);
}
public static String addAndWhere(String hql, HqlDataFilter filter) {
if (!checkWhere(filter)) {
return hql;
}
return addWhere(hql, filter, "and");
}
public static String addOrWhere(String hql, HqlDataFilter filter) {
if (!checkWhere(filter)) {
return hql;
}
return addWhere(hql, filter, "or");
}
public static String addOrderBy(String hql, HqlDataFilter filter) {
if (filter == null || filter.getOrderBy() == null || filter.getOrderBy().isEmpty()) {
return hql;
}
if (!hql.contains("order by")) {
hql += " order by ";
}
hql += filter.getOrderBy();
return hql;
}
public static void addParameters(Query query, HqlDataFilter filter) {
if (filter == null) {
return;
}
for (String key : filter.getParamKeys()) {
if (filter.getParam(key) instanceof Collection<?>) {
query.setParameterList(key, (Collection) filter.getParam(key));
} else {
query.setParameter(key, filter.getParam(key));
}
}
}
private static boolean checkWhere(HqlDataFilter filter) {
return filter != null && filter.getWhere() != null && !filter.getWhere().isEmpty();
}
private static String addWhere(String hql, HqlDataFilter filter, String operator) {
if (hql.toLowerCase().contains("where") && hql.toLowerCase().contains("order by")) {
String[] split = hql.split("order by");
hql = split[0] + " " + operator + " (" + filter.getWhere() + ") order by " + split[1];
return hql;
}
if (hql.toLowerCase().contains("where")) {
hql += " " + operator + " (" + filter.getWhere() + ")";
return hql;
}
if (hql.toLowerCase().contains("order by")) {
String[] split = hql.split("order by");
hql = split[0] + " where (" + filter.getWhere() + ") order by " + split[1];
return hql;
}
hql += " where (" + filter.getWhere() + ")";
return hql;
}
}

@ -23,5 +23,6 @@ public interface Service<T> {
public Module getModule();
public List<Report> getReports();
public boolean canPrintRecord(T entity);
public List<Class<?>> getEntityClasses();
}

@ -1,17 +1,41 @@
package info.bukova.isspst.services.dbinfo;
import info.bukova.isspst.Constants;
import info.bukova.isspst.dao.BaseDao;
import info.bukova.isspst.dao.RequirementDao;
import info.bukova.isspst.dao.TripBillApprovalDao;
import info.bukova.isspst.dao.TripRequirementDao;
import info.bukova.isspst.data.DbInfo;
import info.bukova.isspst.data.RequirementBase;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.services.AbstractService;
import info.bukova.isspst.services.requirement.RequirementBaseService;
import info.bukova.isspst.services.requirement.RequirementService;
import info.bukova.isspst.services.requirement.TripRequirementService;
import info.bukova.isspst.services.tripbill.TripBillApprovalService;
import org.hibernate.SQLQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.SQLQuery;
import org.springframework.transaction.annotation.Transactional;
public class DbInfoServiceImpl extends AbstractService<DbInfo> implements DbInfoService
{
@Autowired
private TripBillApprovalService tripBillApprovalService;
@Autowired
private TripBillApprovalDao tripBillApprovalDao;
@Autowired
private TripRequirementService tripRequirement;
@Autowired
private TripRequirementDao tripRequirementDao;
@Autowired
private RequirementService requirementService;
@Autowired
private RequirementDao requirementDao;
private DbInfo getDbInfo()
{
DbInfo dbInfo = null;
@ -142,10 +166,96 @@ public class DbInfoServiceImpl extends AbstractService<DbInfo> implements DbInfo
sq.executeUpdate();
}
if (dbVersion > 0 && dbVersion < 6) {
sql = "INSERT INTO SEASON(DESCRIPTION, VALID_FROM, VALID_TO, ACTIVE) " +
"VALUES ('2015', '2015-01-01', '2015-12-31', 0)";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "INSERT INTO SEASON(DESCRIPTION, VALID_FROM, VALID_TO, ACTIVE) " +
"VALUES ('2016', '2016-01-01', NULL, 1)";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE NUMBERSERIES SET SEASON_ID = 2";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "INSERT INTO NUMBERSERIES(MODULE, PREFIX, NUMBER, SEASON_ID) " +
"VALUES ('REQUIREMENTS', 'P', 2528, 1)";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "INSERT INTO NUMBERSERIES(MODULE, PREFIX, NUMBER, SEASON_ID) " +
"VALUES ('ORDER', 'OBJ', 55, 1)";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
// rozdeleni dat do sezon
sql = "UPDATE REQUIREMENT SET SEASON_ID = 2 WHERE NUMSER LIKE 'P16%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE REQUIREMENT SET SEASON_ID = 1 WHERE NUMSER LIKE 'P0%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIPREQUIREMENT SET SEASON_ID = 2 WHERE NUMSER LIKE 'P16%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIPREQUIREMENT SET SEASON_ID = 1 WHERE NUMSER LIKE 'P0%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE ORDERS SET SEASON_ID = 2 WHERE NUMSER LIKE 'OBJ16%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE ORDERS SET SEASON_ID = 1 WHERE NUMSER LIKE 'OBJ0%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIP_BILL_APPROVAL SET SEASON_ID = 2 " +
" WHERE TRIPBILL_ID in " +
" (SELECT tb.ID FROM TRIP_BILL AS tb " +
" JOIN TRIPREQUIREMENT ON TRIPREQUIREMENT.ID = tb.REQUIREMENT_ID WHERE NUMSER LIKE 'P16%')";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIP_BILL_APPROVAL SET SEASON_ID = 1 " +
"WHERE TRIPBILL_ID in " +
"(SELECT tb.ID FROM TRIP_BILL AS tb " +
"JOIN TRIPREQUIREMENT ON TRIPREQUIREMENT.ID = tb.REQUIREMENT_ID WHERE NUMSER LIKE 'P0%')";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIP_BILL tb JOIN TRIPREQUIREMENT ON TRIPREQUIREMENT.ID = tb.REQUIREMENT_ID " +
"SET tb.SEASON_ID = 2 WHERE NUMSER LIKE 'P16%'";
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
sql = "UPDATE TRIP_BILL tb JOIN TRIPREQUIREMENT ON TRIPREQUIREMENT.ID = tb.REQUIREMENT_ID " +
"SET tb.SEASON_ID = 1 WHERE NUMSER LIKE 'P0%'";;
sq = dao.getSession().createSQLQuery(sql);
sq.executeUpdate();
}
if (dbVersion < 7) {
setApproveDate((RequirementBaseService)tripBillApprovalService, (BaseDao)tripBillApprovalDao);
setApproveDate((RequirementBaseService)tripRequirement, (BaseDao)tripRequirementDao);
setApproveDate((RequirementBaseService)requirementService, (BaseDao)requirementDao);
}
this.updateDatabaseVersion();
}
}
private void setApproveDate(RequirementBaseService<RequirementBase> service, BaseDao<RequirementBase> daoReq) {
for (RequirementBase req : service.getAll()) {
if (req.getState() == RequirementState.APPROVED) {
service.loadAuthItems(req);
req.setApproveDate(req.getLastApproveDate());
daoReq.modify(req);
}
}
}
@Override
@Transactional
public void updateDatabaseVersion()

@ -1,6 +1,8 @@
package info.bukova.isspst.services.invoicing;
import info.bukova.isspst.data.Invoicing;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.Service;
@ -10,6 +12,8 @@ import java.util.List;
public interface InvoicingService extends Service<Invoicing> {
public BigDecimal totalInvoicedForWorkgroup(Workgroup workgroup);
public BigDecimal totalInvoicedForWorkgroupAndSeason(Workgroup workgroup, Season season);
public void loadReqItems(Invoicing invoicing);
@ -20,4 +24,14 @@ public interface InvoicingService extends Service<Invoicing> {
public List<Invoicing> getPendingList();
public List<Invoicing> getArchiveList();
public Invoicing getForRequirement(Requirement req);
public List<Invoicing> getMaterialPendingList();
public List<Invoicing> getMaterialArchiveList();
public List<Invoicing> getServicesPendingList();
public List<Invoicing> getServicesArchiveList();
}

@ -1,29 +1,43 @@
package info.bukova.isspst.services.invoicing;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.Invoicing;
import info.bukova.isspst.data.InvoicingItem;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.LazyLoader;
import java.math.BigDecimal;
import java.util.List;
import info.bukova.isspst.services.settings.SeasonService;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
public class InvoicingServiceImpl extends AbstractOwnedService<Invoicing> implements
InvoicingService {
@Autowired
private SeasonService seasonService;
@Override
@Transactional
public BigDecimal totalInvoicedForWorkgroup(Workgroup workgroup) {
return totalInvoicedForWorkgroupAndSeason(workgroup, seasonService.getActive());
}
@Override
@Transactional
public BigDecimal totalInvoicedForWorkgroupAndSeason(Workgroup workgroup, Season season) {
Query q = dao.getQuery("select sum(inv.totalInvoiced) "
+ "from Invoicing inv join inv.requirement rq join rq.workgroup w "
+ "where w = :workgroup ");
+ "where w = :workgroup and rq.season = :season");
q.setParameter("workgroup", workgroup);
q.setParameter("season", season);
return (BigDecimal) q.uniqueResult();
}
@ -45,6 +59,14 @@ public class InvoicingServiceImpl extends AbstractOwnedService<Invoicing> implem
invoicing.setItems(inv.getItems());
}
@Transactional
@LazyLoader
public void loadReqAuth(Invoicing invoicing) {
Invoicing inv = getById(invoicing.getId());
Hibernate.initialize(inv.getRequirement().getAuthorization());
invoicing.getRequirement().setAuthorization(inv.getRequirement().getAuthorization());
}
@Override
public void calculate(Invoicing invoicing) {
BigDecimal total = BigDecimal.ZERO;
@ -92,4 +114,53 @@ public class InvoicingServiceImpl extends AbstractOwnedService<Invoicing> implem
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where inv.completed = true order by rq.numser");
return q.list();
}
@Override
@Transactional
public Invoicing getForRequirement(Requirement req) {
Query query = dao.getQuery("select invoice from Invoicing invoice join invoice.requirement rq where rq.id = :reqId");
query.setParameter("reqId", req.getId());
return (Invoicing) query.uniqueResult();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getMaterialPendingList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed Is Null or inv.completed = false) and (rq.kind = :kind) order by rq.numser desc");
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getMaterialArchiveList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed = true) and (rq.kind = :kind) order by rq.numser desc");
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getServicesPendingList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed Is Null or inv.completed = false) and (rq.kind = :kind) order by rq.numser desc");
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Invoicing> getServicesArchiveList() {
Query q = dao.getQuery("select inv from Invoicing as inv join fetch inv.requirement rq join fetch rq.ownedBy where (inv.completed = true) and (rq.kind = :kind) order by rq.numser desc");
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
}
}

@ -0,0 +1,14 @@
package info.bukova.isspst.services.limits;
import info.bukova.isspst.services.IsspstException;
/**
* @author Pepa Rokos
*/
public class LimitException extends IsspstException {
public LimitException(String reason) {
setReason(reason);
}
}

@ -0,0 +1,17 @@
package info.bukova.isspst.services.limits;
import info.bukova.isspst.data.Limit;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.Service;
import java.util.List;
/**
* @author Pepa Rokos
*/
public interface LimitService extends Service<Limit> {
List<Limit> getForSeason(Season season);
Limit getForWorkgroupAndSeason(Workgroup wg, Season season);
Limit getForWorkgroup(Workgroup wg);
}

@ -0,0 +1,62 @@
package info.bukova.isspst.services.limits;
import info.bukova.isspst.data.Limit;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.settings.SeasonService;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author Pepa Rokos
*/
public class LimitServiceImpl extends AbstractOwnedService<Limit> implements LimitService {
@Autowired
private SeasonService seasonService;
@Override
@Transactional
public List<Limit> getForSeason(Season season) {
Query q = dao.getQuery("from Limit where season = :season");
q.setParameter("season", season);
return q.list();
}
@Override
@Transactional
public Limit getForWorkgroupAndSeason(Workgroup wg, Season season) {
Query q = dao.getQuery("from Limit where workgroup = :wg and season = :season");
q.setParameter("wg", wg);
q.setParameter("season", season);
return (Limit) q.uniqueResult();
}
@Override
@Transactional
public Limit getForWorkgroup(Workgroup wg) {
return getForWorkgroupAndSeason(wg, seasonService.getActive());
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
public void add(Limit entity) {
if (getForWorkgroupAndSeason(entity.getWorkgroup(),entity.getSeason()) != null) {
throw new LimitException("LimitExists");
}
super.add(entity);
}
@Override
protected Limit createEntity() {
Limit limit = new Limit();
limit.setSeason(seasonService.getActive());
return limit;
}
}

@ -1,11 +1,18 @@
package info.bukova.isspst.services.numberseries;
import info.bukova.isspst.data.NumberSeries;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.services.Service;
import java.util.List;
public interface NumberSeriesService extends Service<NumberSeries>
{
public NumberSeries getNumberSerie(String module);
public NumberSeries getNumberSerieForSeason(String module, Season season);
public void increase(NumberSeries ns);
public List<NumberSeries> getSeriesForSeason(Season season);
}

@ -1,24 +1,48 @@
package info.bukova.isspst.services.numberseries;
import info.bukova.isspst.data.NumberSeries;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.services.AbstractService;
import info.bukova.isspst.services.settings.SeasonService;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public class NumberSeriesServiceImpl extends AbstractService<NumberSeries> implements NumberSeriesService
{
@Autowired
private SeasonService seasonService;
@Transactional
@Override
public NumberSeries getNumberSerie(String module) {
return getNumberSerieForSeason(module, seasonService.getActive());
}
@Transactional
@Override
public NumberSeries getNumberSerie(String module)
{
return this.selectSingle("from NumberSeries where MODULE = '" + module + "'");
public NumberSeries getNumberSerieForSeason(String module, Season season) {
Query q = dao.getQuery("from NumberSeries where module = :m and season = :s");
q.setParameter("m", module);
q.setParameter("s", season);
return (NumberSeries) q.uniqueResult();
}
@Transactional
@Override
public void increase(NumberSeries ns)
{
public void increase(NumberSeries ns) {
ns.setNumber(ns.getNumber() + 1);
this.update(ns);
}
@Transactional
@Override
public List<NumberSeries> getSeriesForSeason(Season season) {
Query q = dao.getQuery("from NumberSeries where season = :s");
q.setParameter("s", season);
return q.list();
}
}

@ -10,16 +10,16 @@ import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.services.settings.GlobalSettingsService;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import info.bukova.isspst.services.settings.SeasonService;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class OrderServiceImpl extends AbstractOwnedService<Order> implements
OrderService {
@ -29,6 +29,9 @@ public class OrderServiceImpl extends AbstractOwnedService<Order> implements
@Autowired
private RequirementItemDao requirementItemDao;
@Autowired
private SeasonService seasonService;
@Override
@PreAuthorize("hasPermission(this, 'PERM_ADD')")
public Order createOrder(List<JoinedItem> items) {
@ -46,6 +49,7 @@ public class OrderServiceImpl extends AbstractOwnedService<Order> implements
}
order.setTotal(total);
order.setSeason(seasonService.getActive());
return order;
}
@ -76,7 +80,7 @@ public class OrderServiceImpl extends AbstractOwnedService<Order> implements
public List<Order> getAll()
{
Query q = dao.getQuery("select o from Order o join fetch o.ownedBy");
return q.list();
return filterQuery(q).list();
}
@LazyLoader("form")

@ -3,17 +3,14 @@ package info.bukova.isspst.services.requirement;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.Workgroup;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
public class ReqMaterialServiceImpl extends RequirementServiceImpl implements RequirementService, RequirementBaseService<Requirement>
{
@Autowired
@ -38,10 +35,10 @@ public class ReqMaterialServiceImpl extends RequirementServiceImpl implements Re
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Requirement> getMy()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " where ownedBy = :owner and kind = :kind");
q.setParameter("owner", getLoggedInUser());
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_MATERIAL);
return super.getMy();
}
@SuppressWarnings("unchecked")
@ -51,11 +48,10 @@ public class ReqMaterialServiceImpl extends RequirementServiceImpl implements Re
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_CENTRE_REQ')")
public List<Requirement> getCentreReq()
{
List<Workgroup> wgList = workgroupService.getUserCentres(getLoggedInUser());
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.centre c where c in (:wgList) and kind = :kind order by tr.numser");
q.setParameterList("wgList", wgList);
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_MATERIAL);
return super.getCentreReq();
}
@SuppressWarnings("unchecked")
@ -65,13 +61,10 @@ public class ReqMaterialServiceImpl extends RequirementServiceImpl implements Re
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_WORKGROUP_REQ')")
public List<Requirement> getWorkgroupReq()
{
List<Workgroup> wgList = workgroupService.getUserWorkgroups(getLoggedInUser());
Query q = dao.getQuery("select tr from "
+ dao.getEntityName()
+ " tr join fetch tr.ownedBy join tr.workgroup w where w in (:wgList) and kind = :kind order by tr.numser");
q.setParameterList("wgList", wgList);
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_MATERIAL);
return super.getWorkgroupReq();
}
@SuppressWarnings("unchecked")
@ -80,8 +73,9 @@ public class ReqMaterialServiceImpl extends RequirementServiceImpl implements Re
@PreAuthorize("hasPermission(this, 'PERM_SHOW_ALL_REQ')")
public List<Requirement> getAll()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " as tr join fetch tr.ownedBy where kind = :kind order by tr.numser");
q.setParameter("kind", Constants.REQ_TYPE_MATERIAL);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_MATERIAL);
return super.getAll();
}
}

@ -3,17 +3,14 @@ package info.bukova.isspst.services.requirement;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.Workgroup;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
public class ReqServicesServiceImpl extends RequirementServiceImpl implements RequirementService, RequirementBaseService<Requirement>
{
@Autowired
@ -38,10 +35,10 @@ public class ReqServicesServiceImpl extends RequirementServiceImpl implements Re
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<Requirement> getMy()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " where ownedBy = :owner and kind = :kind");
q.setParameter("owner", getLoggedInUser());
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_SERVICES);
return super.getMy();
}
@SuppressWarnings("unchecked")
@ -51,11 +48,10 @@ public class ReqServicesServiceImpl extends RequirementServiceImpl implements Re
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_CENTRE_REQ')")
public List<Requirement> getCentreReq()
{
List<Workgroup> wgList = workgroupService.getUserCentres(getLoggedInUser());
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.centre c where c in (:wgList) and kind = :kind order by tr.numser");
q.setParameterList("wgList", wgList);
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_SERVICES);
return super.getCentreReq();
}
@SuppressWarnings("unchecked")
@ -65,13 +61,10 @@ public class ReqServicesServiceImpl extends RequirementServiceImpl implements Re
@PostFilter("hasPermission(filterObject, 'PERM_SHOW_WORKGROUP_REQ')")
public List<Requirement> getWorkgroupReq()
{
List<Workgroup> wgList = workgroupService.getUserWorkgroups(getLoggedInUser());
Query q = dao.getQuery("select tr from "
+ dao.getEntityName()
+ " tr join fetch tr.ownedBy join tr.workgroup w where w in (:wgList) and kind = :kind order by tr.numser");
q.setParameterList("wgList", wgList);
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_SERVICES);
return super.getWorkgroupReq();
}
@SuppressWarnings("unchecked")
@ -80,8 +73,9 @@ public class ReqServicesServiceImpl extends RequirementServiceImpl implements Re
@PreAuthorize("hasPermission(this, 'PERM_SHOW_ALL_REQ')")
public List<Requirement> getAll()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " as tr join fetch tr.ownedBy where kind = :kind order by tr.numser");
q.setParameter("kind", Constants.REQ_TYPE_SERVICES);
return q.list();
hqlFilter.setDataClass(Requirement.class);
hqlFilter.andFilter("kind = :kind");
hqlFilter.setParam("kind", Constants.REQ_TYPE_SERVICES);
return super.getAll();
}
}

@ -2,6 +2,7 @@ package info.bukova.isspst.services.requirement;
import info.bukova.isspst.data.RequirementBase;
import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workflow;
import info.bukova.isspst.services.Service;
import java.util.Date;
@ -22,9 +23,11 @@ public interface RequirementBaseService<T extends RequirementBase> extends Servi
public void loadType(T data);
public void loadWorkflow(T data);
public void approve(T entity);
public void approve(T entity, Date approveDate);
public void approve(T entity, Date approveDate, byte[] signedPdf);
public boolean canApprove(T entity);
public List<User> getNextApprover(T entity);
public boolean prepareSignData(T entity, Date approveDate);
public Workflow getNextWorkflow(T entity);
public List<T> getMy();

@ -1,33 +1,55 @@
package info.bukova.isspst.services.requirement;
import info.bukova.isspst.Constants;
import info.bukova.isspst.Module;
import info.bukova.isspst.ModuleUtils;
import info.bukova.isspst.data.AuthItem;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.JobMapping;
import info.bukova.isspst.data.RequirementBase;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.Role;
import info.bukova.isspst.data.SettingsData;
import info.bukova.isspst.data.SignedDocument;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workflow;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.mail.MailMessage;
import info.bukova.isspst.mail.Mailer;
import info.bukova.isspst.mail.MessageBuilder;
import info.bukova.isspst.reporting.Generator;
import info.bukova.isspst.reporting.GeneratorFactory;
import info.bukova.isspst.reporting.ParamFiller;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportDefinition;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.HqlDataFilter;
import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.services.Service;
import info.bukova.isspst.services.settings.GlobalSettingsService;
import info.bukova.isspst.services.settings.SeasonService;
import info.bukova.isspst.services.signeddocs.SignedDocumentService;
import info.bukova.isspst.services.users.UserService;
import info.bukova.isspst.services.workgroups.WorkgroupService;
import info.bukova.isspst.signapi.SignData;
import info.bukova.isspst.storage.FileStorage;
import info.bukova.isspst.storage.ReportFileStorage;
import info.bukova.isspst.storage.StorageException;
import org.hibernate.LazyInitializationException;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* @author Pepa Rokos
@ -50,6 +72,25 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
private UserService userService;
@Autowired
protected WorkgroupService workgroupService;
@Autowired
private ReportDefinition reportDefinition;
@Autowired
private ParamFiller paramFiller;
@Autowired
private GeneratorFactory genFactory;
@Autowired
private ServletContext servletContext;
@Autowired
private FileStorage storage;
@Autowired
private SignedDocumentService signedDocumentService;
@Autowired
private ReportFileStorage signedDocStorage;
@Autowired
private SeasonService seasonService;
private final static Logger logger = LoggerFactory.getLogger(RequirementBaseServiceImpl.class);
@Override
@Transactional
@ -58,7 +99,11 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
Workgroup reqWorkgroup = null;
for (Workgroup w : workgroupService.getUserWorkgroups(getLoggedInUser())) {
if (workgroupService.getMembers(entity.getCentre()).contains(w)) {
reqWorkgroup = w;
for (Role r : workgroupService.getUserWorkgroupRoles(w, getLoggedInUser())) {
if (r.getAuthority().equals(Constants.ROLE_USER)) {
reqWorkgroup = w;
}
}
}
}
@ -69,7 +114,9 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
if (!canAdd(entity)) {
throw new AddRequirementException();
}
entity.setSeason(seasonService.getActive());
this.addWorkflow(entity);
entity.setNumser(this.getNumberSerie());
@ -100,7 +147,8 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
}
protected void postAdd(T entity) {
if (canApprove(entity)) {
Workflow wf = getNextWorkflow(entity);
if (canApprove(entity) && (wf.getSignature() == null || !wf.getSignature())) {
approve(entity);
} else {
this.sendToApprovers(entity);
@ -119,6 +167,7 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
workflow.setLimit(w.getLimit());
workflow.setOrder(w.getOrder());
workflow.setRole(w.getRole());
workflow.setSignature(w.getSignature());
entity.getWorkflow().add(workflow);
}
}
@ -214,7 +263,7 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
}
}
protected void approve(T entity, User user, Date approveDate) {
protected void approve(T entity, User user, Date approveDate, byte[] signedPdf) {
T e = (T) dao.getById(entity.getId());
if (e.getReqDate().getTime() > approveDate.getTime()) {
@ -240,12 +289,19 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
if (getNextWorkflow(e) == null) {
e.setState(RequirementState.APPROVED);
e.setApproveDate(approveDate);
} else {
e.setState(RequirementState.PARTIALLY);
}
super.update(e);
if (signedPdf != null) {
saveSignedDoc(e, signedPdf);
} else if (wf.getSignature() != null && wf.getSignature() && !signatureNotRequired(wf)) {
throw new ApproveException("ErrApproveMustBeSigned");
}
if (!autoApprove(e, approveDate)) {
this.sendToApprovers(e);
@ -272,8 +328,17 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
postApprove(e);
}
/**
* Check pro automatické schválení, kdy není třeba podepisovat- nadlimitní nákupy se neautorizují...
* @param wf Další krok schválení
* @return true pokud není potřeba podepisovat. Zde vrací vždy false, v případě potřeby nutno překrýt.
*/
protected boolean signatureNotRequired(Workflow wf) {
return false;
}
protected void approve(T entity, User user) {
approve(entity, user, new Date());
approve(entity, user, new Date(), null);
}
@Override
@ -286,8 +351,8 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
@Override
@Transactional
@PreAuthorize("this.canApprove(#entity)")
public void approve(T entity, Date approveDate) {
approve(entity, getLoggedInUser(), approveDate);
public void approve(T entity, Date approveDate, byte[] signedPdf) {
approve(entity, getLoggedInUser(), approveDate, signedPdf);
}
/**
@ -310,6 +375,30 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
}
protected void saveSignedDoc(T entity, byte[] signedPdf) {
DataModel reportEntity = entityForSignReport(entity);
SignedDocumentItem signedItem = signedDocumentService.getItem(entityForSignReport(entity), getSignReport(entity).getReportId());
if (signedItem == null) {
SignedDocument signDoc = new SignedDocument();
signDoc.setDescription(entity.getDescription());
signDoc.setNumser(entity.getNumser());
signDoc.setRecordId(reportEntity.getId());
signDoc.setModuleName(ModuleUtils.getModule(reportEntity, servletContext).getId());
signDoc.setSignDate(entity.getLastApproveDate());
SignedDocumentItem item = new SignedDocumentItem();
item.setReportId(reportDefinition.getReport().getReportId());
item.setReportName(reportDefinition.getReport().getName());
signDoc.addItem(item);
signedDocStorage.saveFile(signedPdf, item);
signedDocumentService.addFromApprove(signDoc);
} else {
signedDocStorage.saveFile(signedPdf, signedItem);
}
}
@Override
@Transactional
public boolean canApprove(T entity) {
@ -320,8 +409,12 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
return false;
}
protected Workflow getNextWorkflow(T e) {
@Override
@Transactional
public Workflow getNextWorkflow(T entity) {
T e = dao.getById(entity.getId());
AuthItem authItem = null;
if (e.getWorkflow() == null) {
return null;
@ -357,9 +450,10 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<T> getMy()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " where ownedBy = :owner");
q.setParameter("owner", getLoggedInUser());
return q.list();
Query q = dao.getQuery("from " + dao.getEntityName());
HqlDataFilter f = new HqlDataFilter("ownedBy = :owner");
f.setParam("owner", getLoggedInUser());
return filterQuery(q, f).list();
}
@SuppressWarnings("unchecked")
@ -370,9 +464,10 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
public List<T> getCentreReq()
{
List<Workgroup> wgList = workgroupService.getUserCentres(getLoggedInUser());
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.centre c where c in (:wgList) order by tr.numser");
q.setParameterList("wgList", wgList);
return q.list();
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.centre c");
HqlDataFilter f = new HqlDataFilter("c in (:wgList)", "tr.numser desc");
f.setParam("wgList", wgList);
return filterQuery(q, f).list();
}
@SuppressWarnings("unchecked")
@ -383,9 +478,10 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
public List<T> getWorkgroupReq()
{
List<Workgroup> wgList = workgroupService.getUserWorkgroups(getLoggedInUser());
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.workgroup w where w in (:wgList) order by tr.numser");
q.setParameterList("wgList", wgList);
return q.list();
Query q = dao.getQuery("select tr from " + dao.getEntityName() + " tr join fetch tr.ownedBy join tr.workgroup w");
HqlDataFilter f = new HqlDataFilter("w in (:wgList)", "tr.numser desc");
f.setParam("wgList", wgList);
return filterQuery(q, f).list();
}
@SuppressWarnings("unchecked")
@ -394,8 +490,9 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
@PreAuthorize("hasPermission(this, 'PERM_SHOW_ALL_REQ')")
public List<T> getAll()
{
Query q = dao.getQuery("from " + dao.getEntityName() + " as tr join fetch tr.ownedBy order by tr.numser");
return q.list();
Query q = dao.getQuery("from " + dao.getEntityName() + " as tr join fetch tr.ownedBy");
HqlDataFilter f = new HqlDataFilter("", "tr.numser desc");
return filterQuery(q, f).list();
}
@Override
@ -408,4 +505,108 @@ public abstract class RequirementBaseServiceImpl<T extends RequirementBase> exte
return Constants.PERM_DELETE_NEW;
}
@Override
@Transactional
public boolean prepareSignData(T entity, Date approveDate) {
SignData data = new SignData();
sessionData.setProperty(Constants.KEY_SIGN_DATA, data);
data.setSignGuid(UUID.randomUUID().toString());
sessionData.setProperty(Constants.KEY_SIGN_GUID, data.getSignGuid());
reportDefinition.clear();
reportDefinition.setSingleObject(entityForSignReport(entity));
Report report = getSignReport(entity);
if (report == null) {
return false;
}
reportDefinition.setReport(report);
Module module = ModuleUtils.getModule(entityForSignReport(entity), servletContext);
reportDefinition.setService((Service<Object>) ModuleUtils.getServiceInstance(module, servletContext));
paramFiller.fill();
Generator gen = genFactory.createGenerator(reportDefinition);
data.setPdfData(gen.generate());
data.setDescription(entity.getDescription());
data.setNumser(entity.getNumser());
data.setSignDate(approveDate);
data.setSigned(signedDocumentService.getItem(entityForSignReport(entity), report.getReportId()) != null);
if (getNextWorkflow(entity).getCentre()) { // viditelné podpisy lze pouze na urovni strediska
if (entity.getState() == RequirementState.NEW) {
data.setAreaId(1);
} else {
loadAuthItems(entity);
int wgCount = 0;
for (Workflow wf : entity.getWorkflow()) {
if (!wf.getCentre()) {
++wgCount;
}
}
data.setAreaId(entity.getAuthorization().size() - wgCount + 1);
}
if (userService.getUserSettings().getSignatureFile() != null) {
data.setSignImg(storage.fileData(userService.getUserSettings().getSignatureFile()));
}
}
return true;
}
protected DataModel entityForSignReport(T entity) {
return entity;
}
private Report getSignReport(T entity) {
Module module = ModuleUtils.getModule(entityForSignReport(entity), servletContext);
Report report = null;
int reportId = Constants.SIGN_REPORT_MAP.get(entity.getClass()) == null ? 0 : Constants.SIGN_REPORT_MAP.get(entity.getClass());
for (Report r : module.getReports()) {
if (r.isSignable()) {
if (reportId == 0) {
report = r;
break;
} else if (reportId == r.getReportId()) {
report = r;
break;
}
}
}
return report;
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_EDIT') or hasPermission(#entity, this.getUpdateEntityPermission())")
public void update(T entity) {
entity.getAuthorization().clear();
entity.setState(RequirementState.NEW);
super.update(entity);
try {
signedDocumentService.deleteForEntity(entity);
} catch (StorageException e) {
logger.warn(e.getMessage());
}
sendToApprovers(entity);
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_DELETE') or hasPermission(#entity, this.getDeleteEntityPermission())")
public void delete(T entity) {
super.delete(entity);
try {
signedDocumentService.delFromApprove(signedDocumentService.getForEntity(entity));
} catch (StorageException e) {
logger.warn(e.getMessage());
}
}
}

@ -2,6 +2,7 @@ package info.bukova.isspst.services.requirement;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.Invoicing;
import info.bukova.isspst.data.Limit;
import info.bukova.isspst.data.Requirement;
import info.bukova.isspst.data.RequirementItem;
import info.bukova.isspst.data.RequirementState;
@ -10,9 +11,10 @@ import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workflow;
import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.services.invoicing.InvoicingService;
import info.bukova.isspst.services.limits.LimitService;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
@ -33,6 +35,8 @@ public class RequirementServiceImpl extends RequirementBaseServiceImpl<Requireme
private RequirementTypeService reqTypeService;
@Autowired
private InvoicingService invoicingService;
@Autowired
private LimitService limitService;
@Override
protected Requirement createEntity()
@ -60,36 +64,45 @@ public class RequirementServiceImpl extends RequirementBaseServiceImpl<Requireme
if ((entity.getSumTotal() != null)
&& (entity.getSumTotal().compareTo(nextWf.getLimit()) == -1))
{
approve(entity, approvers.get(0), approveDate);
approve(entity, approvers.get(0), approveDate, null);
return true;
}
return false;
}
/**
* Nadlimitní autorizovat bez podpisu
* @param wf Další krok schválení
* @return true, pokud má role nastavený limit- automatické schválení podlimitního požadavku
*/
@Override
protected boolean signatureNotRequired(Workflow wf) {
return wf.getLimit() != null;
}
@Override
protected boolean canAdd(Requirement entity)
{
if (entity.getWorkgroup() != null && entity.getWorkgroup().getLimit() != null && entity.getWorkgroup().getLimit().compareTo(BigDecimal.ZERO) != 0)
{
if (entity.getWorkgroup() != null) {
Limit limit = limitService.getForWorkgroup(entity.getWorkgroup());
if (limit == null) {
return true;
}
BigDecimal total = invoicingService.totalInvoicedForWorkgroup(entity.getWorkgroup());
if (total == null)
{
if (total == null) {
total = BigDecimal.ZERO;
}
total = total.add(entity.getSumTotal());
if (total.compareTo(entity.getWorkgroup().getLimit()) <= 0)
{
if (total.compareTo(limit.getLimit()) <= 0) {
return true;
}
}
else
{
else {
return true;
}
@ -244,11 +257,19 @@ public class RequirementServiceImpl extends RequirementBaseServiceImpl<Requireme
@Override
@Transactional
public BigDecimal getInvoicedAmount(Requirement req) {
Query query = dao.getQuery("select invoice from Invoicing invoice join invoice.requirement rq where rq.id = :reqId");
query.setParameter("reqId", req.getId());
Invoicing inv = (Invoicing) query.uniqueResult();
Invoicing inv = invoicingService.getForRequirement(req);
return inv != null ? inv.getTotalInvoiced() : null;
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_EDIT') or hasPermission(#entity, this.getUpdateEntityPermission())")
public void update(Requirement entity) {
super.update(entity);
Invoicing inv = invoicingService.getForRequirement(entity);
if (inv != null) {
invoicingService.delete(inv);
}
}
}

@ -57,8 +57,6 @@ public class TripRequirementServiceImpl extends RequirementBaseServiceImpl<TripR
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_EDIT') or hasPermission(#entity, this.getUpdateEntityPermission())")
public void update(TripRequirement entity) {
super.update(entity);
if (entity.getState() == RequirementState.APPROVED) {
for (TripBill bill : getBills(entity)) {
TripBill newBill = tripBillService.createTripBill(entity);
@ -75,6 +73,8 @@ public class TripRequirementServiceImpl extends RequirementBaseServiceImpl<TripR
tripBillService.update(bill);
}
}
super.update(entity);
}
@Override
@ -141,25 +141,53 @@ public class TripRequirementServiceImpl extends RequirementBaseServiceImpl<TripR
@Override
protected void postApprove(TripRequirement entity) {
if (entity.getState() == RequirementState.APPROVED) {
if (entity.getState() != RequirementState.APPROVED) {
return;
}
List<TripBill> billList = getBills(entity);
boolean hasOwned = false;
for (TripBill tb : billList) {
if (tb.getOwnedBy().equals(entity.getOwnedBy())) {
hasOwned = true;
break;
}
}
if (!hasOwned) {
TripBill bill = tripBillService.createTripBill(entity);
tripBillService.add(bill);
bill.setOwnedBy(entity.getOwnedBy());
tripBillService.update(bill);
}
if (entity.getBillForPassengers() != null && entity.getBillForPassengers()) {
for (User u : entity.getPassengers()) {
if (!u.equals(entity.getOwnedBy())) {
TripBill passBill = tripBillService.createPassengersBill(entity);
tripBillService.add(passBill);
passBill.setOwnedBy(u);
tripBillService.update(passBill);
}
if (entity.getBillForPassengers() != null && entity.getBillForPassengers()) {
for (User u : entity.getPassengers()) {
if (canCreateBill(entity, u, billList)) {
TripBill passBill = tripBillService.createPassengersBill(entity);
tripBillService.add(passBill);
passBill.setOwnedBy(u);
tripBillService.update(passBill);
}
}
sendMailToPassengers(entity, settingsService.getSettings().getConfReqTripPassenger());
sendMailToPassengers(entity, settingsService.getSettings().getConfReqTripPassenger());
}
}
private boolean canCreateBill(TripRequirement req, User owner, List<TripBill> bills) {
if (owner.equals(req.getOwnedBy())) {
return false;
}
for (TripBill tb : bills) {
if (tb.getOwnedBy().equals(owner)) {
return false;
}
}
return true;
}
@Override

@ -0,0 +1,18 @@
package info.bukova.isspst.services.settings;
import info.bukova.isspst.services.IsspstException;
/**
* @author Pepa Rokos
*/
public class SeasonException extends IsspstException {
SeasonException() {
super();
}
SeasonException(String msg) {
super(msg);
setReason(msg);
}
}

@ -0,0 +1,16 @@
package info.bukova.isspst.services.settings;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.services.Service;
import java.util.List;
/**
* @author Pepa Rokos
*/
public interface SeasonService extends Service<Season> {
Season addSeason();
Season getActive();
List<Season> getAllSeasons();
void setActive(Season season);
}

@ -0,0 +1,100 @@
package info.bukova.isspst.services.settings;
import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.NumberSeries;
import info.bukova.isspst.data.Season;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.numberseries.NumberSeriesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* @author Pepa Rokos
*/
public class SeasonServiceImpl extends AbstractOwnedService<Season> implements SeasonService {
private Season activeSeason;
@Autowired
private NumberSeriesService numberSeriesService;
@Transactional
@Override
public Season addSeason() {
Season season = new Season();
season.setDescription(StringUtils.localize("SeasonsNewSeason"));
season.setValidFrom(new Date());
season.setActive(true);
Season last = selectSingle("from Season where validTo Is Null");
add(season);
last.setValidTo(new Date());
last.setActive(false);
update(last);
activeSeason = null;
List<NumberSeries> numSeries = numberSeriesService.getSeriesForSeason(last);
for (NumberSeries ns: numSeries) {
String txt = ns.getPrefix().replaceAll("[0-9]+", "");
String numTxt = ns.getPrefix().replaceAll("[a-zA-Z]+", "");
int num = 0;
try {
num = Integer.valueOf(numTxt);
} catch (Exception e) {
e.printStackTrace();
}
String newPrefix = txt + String.valueOf(num + 1);
NumberSeries newNumSer = new NumberSeries();
newNumSer.setPrefix(newPrefix);
newNumSer.setModule(ns.getModule());
newNumSer.setNumber(1);
newNumSer.setSeason(season);
numberSeriesService.add(newNumSer);
}
return season;
}
@Transactional
@Override
public Season getActive() {
if (activeSeason == null) {
activeSeason = selectSingle("from Season where active = true");
}
if (activeSeason == null) {
throw new SeasonException("Active_season_not_set");
}
return activeSeason;
}
@Override
@Transactional
public List<Season> getAllSeasons() {
return getAll();
}
@Transactional
@Override
public void setActive(Season season) {
for (Season s: getAll()) {
s.setActive(false);
update(s);
}
Season s = dao.getById(season.getId());
if (s == null) {
throw new SeasonException("Season_not_in_database");
}
s.setActive(true);
activeSeason = s;
}
}

@ -0,0 +1,25 @@
package info.bukova.isspst.services.signeddocs;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.Member;
import info.bukova.isspst.data.SignedDocument;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.services.Service;
import info.bukova.isspst.ui.signeddocs.SignedDocsTreeNode;
import org.zkoss.zul.TreeModel;
import org.zkoss.zul.TreeNode;
import java.util.List;
public interface SignedDocumentService extends Service<SignedDocument> {
SignedDocument getForEntity(DataModel entity);
SignedDocumentItem getItem(DataModel entity, long reportId);
void addFromApprove(SignedDocument document);
void delFromApprove(SignedDocument document);
void deleteForEntity(DataModel entity);
public List<SignedDocument> getActualList();
public List<SignedDocument> getArchiveList();
public TreeModel<TreeNode<SignedDocumentItem>> getTree();
}

@ -0,0 +1,242 @@
package info.bukova.isspst.services.signeddocs;
import info.bukova.isspst.DateTimeUtils;
import info.bukova.isspst.Module;
import info.bukova.isspst.ModuleUtils;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.Member;
import info.bukova.isspst.data.SignedDocument;
import info.bukova.isspst.data.SignedDocumentItem;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.storage.ReportFileStorage;
import java.util.*;
import javax.servlet.ServletContext;
import info.bukova.isspst.ui.signeddocs.SignedDocsTreeNode;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.zul.DefaultTreeModel;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.TreeModel;
import org.zkoss.zul.TreeNode;
public class SignedDocumentServiceImpl extends AbstractOwnedService<SignedDocument> implements SignedDocumentService {
@Autowired
private ServletContext servletContext;
@Autowired
private ReportFileStorage signedDocStorage;
@LazyLoader("grid")
@Transactional
public void lazyLoadItems(SignedDocument signedDocument) {
if (signedDocument == null) {
return;
}
SignedDocument sd = dao.getById(signedDocument.getId());
Hibernate.initialize(sd.getItems());
signedDocument.setItems(sd.getItems());
}
@Override
@Transactional
public SignedDocument getForEntity(DataModel entity) {
Module module = ModuleUtils.getModule(entity, servletContext);
if (module == null) {
return null;
}
Query q = dao.getQuery("from SignedDocument where moduleName = :module and recordId = :record");
q.setParameter("module", module.getId());
q.setParameter("record", entity.getId());
return (SignedDocument) q.uniqueResult();
}
@Override
@Transactional
public SignedDocumentItem getItem(DataModel entity, long reportId) {
SignedDocument doc = getForEntity(entity);
if (doc == null) {
return null;
}
for (SignedDocumentItem item : doc.getItems()) {
if (item.getReportId() == reportId) {
return item;
}
}
return null;
}
@Override
public void addFromApprove(SignedDocument document) {
super.add(document);
}
@Override
public void delFromApprove(SignedDocument document) {
if (document == null) {
return;
}
super.delete(document);
for (SignedDocumentItem item : document.getItems()) {
signedDocStorage.removeFile(item);
}
}
@Override
@Transactional
public void deleteForEntity(DataModel entity) {
SignedDocument doc = getForEntity(entity);
if (doc != null) {
delFromApprove(doc);
}
}
private Date getTresholdDate() {
Date date = DateTimeUtils.getDateDelta(DateTimeUtils.getCurrDate(), Calendar.MONTH, -6);
return date;
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<SignedDocument> getActualList() {
Query q = dao.getQuery("from SignedDocument where signDate >= :refDate");
q.setParameter("refDate", this.getTresholdDate());
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<SignedDocument> getArchiveList() {
Query q = dao.getQuery("from SignedDocument where signDate < :refDate");
q.setParameter("refDate", this.getTresholdDate());
return q.list();
}
@SuppressWarnings("unchecked")
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public TreeModel<TreeNode<SignedDocumentItem>> getTree() {
Query q = queryDao.getQuery("select item "
+ "from SignedDocumentItem as item left join item.signedDocument as rec "
+ "order by rec.moduleName, rec.signDate desc, item.reportName, item.fileName "
);
List<SignedDocumentItem> list = q.list();
SignedDocumentItem lastItem = null;
SignedDocument lastRec = null;
List<SignedDocsTreeNode> agendaNameList = new LinkedList<SignedDocsTreeNode>();
List<SignedDocsTreeNode> signYearList = new LinkedList<SignedDocsTreeNode>();
List<SignedDocsTreeNode> signDateList = new LinkedList<SignedDocsTreeNode>();
List<SignedDocsTreeNode> filesList = null;
int documentsCount = list.size() - 1;
for (int i = 0; i <= documentsCount; i++) {
SignedDocumentItem item = list.get(i);
SignedDocument rec = item.getSignedDocument();
SignedDocsTreeNode itemNode = new SignedDocsTreeNode(item);
boolean isChangedAgendaName = ((i == 0)
|| (i == documentsCount)
|| !lastRec.getAgendaName().equals(rec.getAgendaName())
);
boolean isChangedSignYear = ((i == 0)
|| (i == documentsCount)
|| isChangedAgendaName
|| !DateTimeUtils.isEqualByYear(lastRec.getSignDate(), rec.getSignDate())
);
boolean isChangedSignDate = ((i == 0)
|| (i == documentsCount)
|| isChangedSignYear
|| !DateTimeUtils.isEqualByDate(lastRec.getSignDate(), rec.getSignDate())
);
if (isChangedAgendaName || isChangedSignYear || isChangedSignDate) {
if (isChangedSignDate) {
if (i > 0) {
SignedDocsTreeNode signDateNode = new SignedDocsTreeNode((i == documentsCount ? item : lastItem), filesList);
signDateList.add(signDateNode);
}
filesList = new LinkedList<SignedDocsTreeNode>();
filesList.add(itemNode);
}
if (isChangedSignYear) {
if (i > 0) {
SignedDocsTreeNode signYearNode = new SignedDocsTreeNode((i == documentsCount ? item : lastItem), signDateList);
signYearList.add(signYearNode);
}
signDateList = new LinkedList<SignedDocsTreeNode>();
}
if (isChangedAgendaName) {
if (i > 0) {
SignedDocsTreeNode agendaNode = new SignedDocsTreeNode((i == documentsCount ? item : lastItem), signYearList);
agendaNameList.add(agendaNode);
}
signYearList = new LinkedList<SignedDocsTreeNode>();
}
} else {
filesList.add(itemNode);
}
lastItem = item;
lastRec = lastItem.getSignedDocument();
}
Collections.sort(agendaNameList, new Comparator<SignedDocsTreeNode>() {
@Override
public int compare(SignedDocsTreeNode nodeL, SignedDocsTreeNode nodeR) {
if ((nodeL != null) && (nodeR != null)) {
SignedDocumentItem itemL = nodeL.getData();
SignedDocumentItem itemR = nodeR.getData();
if ((itemL != null) && (itemR != null)) {
SignedDocument recL = itemL.getSignedDocument();
SignedDocument recR = itemR.getSignedDocument();
if ((recL != null) && (recR != null)) {
String nameL = recL.getAgendaName();
String nameR = recR.getAgendaName();
if ((nameL != null) && (nameR != null)) {
return nameL.compareTo(nameR);
}
}
}
}
return 0;
}
}
);
SignedDocsTreeNode root = new SignedDocsTreeNode(null, agendaNameList);
TreeModel<TreeNode<SignedDocumentItem>> tree = new DefaultTreeModel<SignedDocumentItem>(root);
return tree;
}
}

@ -0,0 +1,18 @@
package info.bukova.isspst.services.tripbill;
import info.bukova.isspst.services.IsspstException;
/**
* @author Pepa Rokos
*/
public class PayException extends IsspstException {
public PayException() {
super();
}
public PayException(String message) {
super(message);
setReason(message);
}
}

@ -10,5 +10,6 @@ import info.bukova.isspst.services.requirement.RequirementBaseService;
public interface TripBillApprovalService extends RequirementBaseService<TripBillApproval> {
public TripBillApproval createApproval(TripBill bill);
public void cancelApproval(TripBill bill);
}

@ -1,20 +1,30 @@
package info.bukova.isspst.services.tripbill;
import info.bukova.isspst.Constants;
import info.bukova.isspst.Module;
import info.bukova.isspst.ModuleUtils;
import info.bukova.isspst.StringUtils;
import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.data.RequirementState;
import info.bukova.isspst.data.TripBill;
import info.bukova.isspst.data.TripBillApproval;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.services.IsspstException;
import info.bukova.isspst.services.requirement.RequirementBaseServiceImpl;
import info.bukova.isspst.services.requirement.RequirementTypeService;
import java.util.Date;
import info.bukova.isspst.services.signeddocs.SignedDocumentService;
import info.bukova.isspst.storage.StorageException;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Pepa Rokos
*/
@ -22,6 +32,12 @@ public class TripBillApprovalServiceImpl extends RequirementBaseServiceImpl<Trip
@Autowired
private RequirementTypeService reqTypeService;
@Autowired
private TripBillService tripBillService;
@Autowired
private SignedDocumentService signedDocumentService;
private final static Logger logger = LoggerFactory.getLogger(TripBillApproval.class);
@Override
public TripBillApproval createApproval(TripBill bill) {
@ -32,6 +48,7 @@ public class TripBillApprovalServiceImpl extends RequirementBaseServiceImpl<Trip
TripBillApproval approval = new TripBillApproval();
approval.setCentre(bill.getRequirement().getCentre());
approval.setWorkgroup(bill.getRequirement().getWorkgroup());
approval.setSeason(bill.getSeason());
approval.setReqDate(new Date());
approval.setType(reqTypeService.getTypeById(Constants.REQTYPE_BUSINESSTRIP));
approval.setState(RequirementState.NEW);
@ -53,4 +70,68 @@ public class TripBillApprovalServiceImpl extends RequirementBaseServiceImpl<Trip
postAdd(entity);
}
@Override
protected DataModel entityForSignReport(TripBillApproval entity) {
return entity.getBill();
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_DELETE') or this.canApprove(#bill.approval)")
public void cancelApproval(TripBill bill) {
TripBillApproval approval = bill.getApproval();
if (approval != null) {
super.delete(approval);
}
removeApproval(bill);
}
private void removeApproval(TripBill bill) {
bill.setApproval(null);
tripBillService.update(bill);
try {
signedDocumentService.deleteForEntity(bill);
} catch (StorageException e) {
logger.warn(e.getMessage());
}
}
@Override
public Module getModule() {
return ModuleUtils.getModule(Constants.MOD_TRIPREQUIREMENTS);
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_DELETE') or hasPermission(#entity, this.getDeleteEntityPermission())")
public void delete(TripBillApproval entity) {
TripBill bill = entity.getBill();
if (bill == null) {
Query q = queryDao.getQuery("FROM TripBill WHERE APPROVAL_ID = :appId");
q.setInteger("appId", entity.getId());
bill = (TripBill) q.uniqueResult();
}
if (bill != null) {
dao.delete(entity);
removeApproval(bill);
} else {
super.delete(entity);
}
}
@Override
public List<Report> getReports() {
List<Report> reports = new ArrayList<Report>();
reports.add(new Report(Constants.TRIB_BILLS_REP_ID, false, "Přehled vyúčtovaných CP", "tripBills"));
reports.add(new Report(Constants.TRIB_BILLS_NP_REP_ID, false, "Přehled nevyúčtovaných CP", "tripBillsNP"));
return reports;
}
}

@ -4,6 +4,7 @@ import info.bukova.isspst.data.TripBill;
import info.bukova.isspst.data.TripRequirement;
import info.bukova.isspst.services.Service;
import java.util.Date;
import java.util.List;
public interface TripBillService extends Service<TripBill> {
@ -15,6 +16,7 @@ public interface TripBillService extends Service<TripBill> {
public List<TripBill> getMy();
public void loadOwner(TripBill bill);
public void loadPassengers(TripBill bill);
public void setPaid(TripBill bill, Date date);
/**
* Uloží vyúčtování a nastaví příznak přenosu vyúčtování od žadatele

@ -6,6 +6,7 @@ import info.bukova.isspst.data.TripBill;
import info.bukova.isspst.data.TripBillItem;
import info.bukova.isspst.data.TripRequirement;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.HqlDataFilter;
import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.services.settings.GlobalSettingsService;
import org.hibernate.Hibernate;
@ -23,6 +24,7 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implements
@ -45,6 +47,7 @@ public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implemen
TripBill bill = new TripBill();
bill.setRequirement(requirement);
bill.setSeason(requirement.getSeason());
if (!passengers) {
bill.setDownPayment(requirement.getDownPayment());
@ -132,7 +135,7 @@ public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implemen
}
if (item.getBackDeparture() == null) {
timeBack = (new LocalTime()).withHourOfDay(23).withMinuteOfHour(59);
timeBack = (new LocalTime()).withHourOfDay(23).withMinuteOfHour(00);
allDay = true;
} else {
timeBack = new LocalTime(item.getBackDeparture());
@ -178,9 +181,10 @@ public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implemen
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_READ')")
public List<TripBill> getMy() {
Query q = dao.getQuery("from TripBill where ownedBy = :owner");
q.setParameter("owner", getLoggedInUser());
return q.list();
Query q = dao.getQuery("from TripBill");
HqlDataFilter f = new HqlDataFilter("ownedBy = :owner");
f.setParam("owner", getLoggedInUser());
return filterQuery(q, f).list();
}
@Override
@ -212,6 +216,19 @@ public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implemen
bill.getRequirement().setPassengers(tr.getPassengers());
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_PAY_BILL')")
public void setPaid(TripBill bill, Date date) {
if (bill.getApproval() == null || bill.getApproval().getState() != RequirementState.APPROVED) {
throw new PayException("BillNotApproved");
}
bill.setPaid(true);
bill.setPaidDate(date);
super.update(bill);
}
@Override
@Transactional
@PreAuthorize("hasPermission(this, 'PERM_EDIT') or hasPermission(#entity, this.getUpdateEntityPermission())")
@ -252,7 +269,9 @@ public class TripBillServiceImpl extends AbstractOwnedService<TripBill> implemen
@Override
public boolean canPrintRecord(TripBill entity) {
if (entity.getApproval() != null && entity.getApproval().getState() == RequirementState.APPROVED) {
if (entity.getApproval() != null
&& entity.getApproval().getState() == RequirementState.APPROVED
&& (entity.getPaid() == null || !entity.getPaid())) {
return true;
}

@ -3,9 +3,6 @@ package info.bukova.isspst.services.users;
import info.bukova.isspst.Constants;
import info.bukova.isspst.data.User;
import info.bukova.isspst.security.AuthMethod;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextAdapter;
@ -16,6 +13,8 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
import java.util.Collection;
/**
* Mapovač doménových uživatelů Active Directory na uživatele aplikace. Pokud uživatel není v aplikační databází,
* importu je se tam pomoci {@link LdapUserImporter}. Tento objekt se předává do {@link ActiveDirectoryLdapAuthenticationProvider}.
@ -40,7 +39,8 @@ public class AdUserCtxMapper implements UserDetailsContextMapper {
@Override
public UserDetails mapUserFromContext(DirContextOperations userData,
String username, Collection<? extends GrantedAuthority> authorities) {
username = username.toLowerCase();
try {
User user = (User) userService.loadUserByUsername(username);
return user;

@ -7,15 +7,7 @@ import info.bukova.isspst.data.UserSettingsData;
import info.bukova.isspst.security.AuthMethod;
import info.bukova.isspst.services.AbstractService;
import info.bukova.isspst.services.StringXmlMarshaller;
//import info.bukova.isspst.services.LazyLoader;
import info.bukova.isspst.services.workgroups.WorkgroupService;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.hibernate.LazyInitializationException;
@ -31,6 +23,13 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
//import info.bukova.isspst.services.LazyLoader;
public class UserServiceImpl extends AbstractService<User> implements UserService {
private PasswordEncoder encoder;
@ -220,6 +219,7 @@ public class UserServiceImpl extends AbstractService<User> implements UserServic
}
@Override
@Transactional
public void delete(User entity) {
workgroupService.loadParents(entity);
@ -234,7 +234,7 @@ public class UserServiceImpl extends AbstractService<User> implements UserServic
@Override
@Transactional
public List<User> getUsersForCombo() {
Query q = dao.getQuery("from User u order by u.lastName");
Query q = dao.getQuery("from User u where u.enabled = true order by u.lastName");
return q.list();
}

@ -1,7 +1,5 @@
package info.bukova.isspst.services.workgroups;
import java.util.List;
import info.bukova.isspst.data.JobMapping;
import info.bukova.isspst.data.Member;
import info.bukova.isspst.data.Role;
@ -9,6 +7,8 @@ import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.Service;
import java.util.List;
public interface WorkgroupService extends Service<Workgroup> {
public void addMember(Workgroup workgroup, Member member, Role role);
@ -17,6 +17,7 @@ public interface WorkgroupService extends Service<Workgroup> {
public List<Workgroup> getCentres();
public boolean isMember(Workgroup workgroup, Member member);
public List<Workgroup> getUserCentres(User user);
public List<Workgroup> getUserCentres(User user, boolean userOnly);
public List<Workgroup> getUserWorkgroups(User user);
public List<Role> getUserWorkgroupRoles(Workgroup workgroup, User user);
public List<Member> getMembers(Workgroup workgroup);

@ -8,15 +8,14 @@ import info.bukova.isspst.data.User;
import info.bukova.isspst.data.Workgroup;
import info.bukova.isspst.services.AbstractOwnedService;
import info.bukova.isspst.services.LazyLoader;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.LazyInitializationException;
import org.hibernate.Query;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
public class WorkgroupServiceImpl extends AbstractOwnedService<Workgroup> implements WorkgroupService {
@Override
@ -125,7 +124,7 @@ public class WorkgroupServiceImpl extends AbstractOwnedService<Workgroup> implem
@Override
@Transactional
public List<Workgroup> getUserCentres(User user) {
if (user.equals(getLoggedInUser()) && sessionData.getUserCentres() != null) {
/*if (user.equals(getLoggedInUser()) && sessionData.getUserCentres() != null) {
return sessionData.getUserCentres();
}
@ -150,6 +149,75 @@ public class WorkgroupServiceImpl extends AbstractOwnedService<Workgroup> implem
}
}
}
return centres;*/
return getUserCentres(user, false);
}
@Override
@Transactional
public List<Workgroup> getUserCentres(User user, boolean userOnly) {
if (!userOnly && user.equals(getLoggedInUser()) && sessionData.getUserCentres() != null) {
return sessionData.getUserCentres();
}
if (userOnly && user.equals(getLoggedInUser()) && sessionData.getUserOnlyCentres() != null) {
return sessionData.getUserOnlyCentres();
}
List<Workgroup> parents;
if (userOnly) {
parents = filterUserOnly(user, getParents(user));
} else {
parents = getParents(user);
}
if (parents == null) {
return null;
}
List<Workgroup> centres = new ArrayList<Workgroup>();
for (Workgroup w : parents) {
if (w.isCentre()) {
centres.add(w);
}
}
List<Workgroup> workGroups;
if (userOnly) {
workGroups = filterUserOnly(user, getUserWorkgroups(user));
} else {
workGroups = getUserWorkgroups(user);
}
for (Workgroup w : workGroups) {
loadParents(w);
for (Workgroup centre : w.getParents()) {
if (!centres.contains(centre)) {
centres.add(centre);
}
}
}
return centres;
}
private List<Workgroup> filterUserOnly(User user, List<Workgroup> wgList) {
List<Workgroup> centres = new ArrayList<Workgroup>();
for (Workgroup wg : wgList) {
List<Role> roles = getUserWorkgroupRoles(wg, user);
if (roles == null) {
continue;
}
for (Role r : roles) {
if (r.getAuthority().equals(Constants.ROLE_USER)) {
centres.add(wg);
}
}
}
return centres;
}

@ -0,0 +1,10 @@
package info.bukova.isspst.signapi;
/**
* @author Pepa Rokos
*/
public interface JnlpGenerator {
public byte[] generate();
}

@ -0,0 +1,121 @@
package info.bukova.isspst.signapi;
import org.springframework.beans.factory.annotation.Autowired;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
/**
* @author Pepa Rokos
*/
public class JnlpGeneratorImpl implements JnlpGenerator {
@Autowired
private HttpServletRequest request;
@Override
public byte[] generate() {
String sessionId;
if (request.getParameter("id") != null && !request.getParameter("id").isEmpty()) {
sessionId = request.getParameter("id");
} else {
sessionId = request.getSession().getId();
}
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document document = docBuilder.newDocument();
Element root = document.createElement("jnlp");
root.setAttribute("spec", "1.0+");
String signerUrl = request.getRequestURL().toString();
signerUrl = signerUrl.substring(0, signerUrl.indexOf(request.getServletPath())) + "/api/sign";
root.setAttribute("codebase", signerUrl);
root.setAttribute("href", "signer.jnlp" + "?id=" + sessionId);
document.appendChild(root);
Element info = document.createElement("information");
Element title = document.createElement("title");
title.appendChild(document.createTextNode("Signer component"));
info.appendChild(title);
Element vendor = document.createElement("vendor");
vendor.appendChild(document.createTextNode("bukova.info"));
info.appendChild(vendor);
root.appendChild(info);
Element security = document.createElement("security");
security.appendChild(document.createElement("all-permissions"));
root.appendChild(security);
Element resources = document.createElement("resources");
resources.setAttribute("os", "Linux");
Element j2se = document.createElement("j2se");
j2se.setAttribute("version", "1.8+");
Element jar = document.createElement("jar");
jar.setAttribute("href", "pdfsigner.jar");
resources.appendChild(j2se);
resources.appendChild(jar);
root.appendChild(resources);
Element resourcesWin = document.createElement("resources");
resourcesWin.setAttribute("os", "Windows");
Element j2seWin = document.createElement("j2se");
j2seWin.setAttribute("version", "1.8+");
Element jarWin = document.createElement("jar");
jarWin.setAttribute("href", "pdfsignerWin.jar");
resourcesWin.appendChild(j2seWin);
resourcesWin.appendChild(jarWin);
root.appendChild(resourcesWin);
Element appDesc = document.createElement("application-desc");
appDesc.setAttribute("main-class", "info.bukova.pdfsigner.Main");
Element argUrl = document.createElement("argument");
argUrl.appendChild(document.createTextNode(signerUrl + "/data"));
appDesc.appendChild(argUrl);
Element argSession = document.createElement("argument");
argSession.appendChild(document.createTextNode(sessionId));
appDesc.appendChild(argSession);
root.appendChild(appDesc);
System.out.println(signerUrl);
System.out.println(request.getSession().getId());
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
StreamResult result = new StreamResult(bos);
transformer.transform(source, result);
return bos.toByteArray();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
}

@ -0,0 +1,92 @@
package info.bukova.isspst.signapi;
import java.io.Serializable;
import java.util.Date;
/**
* @author Pepa Rokos
*/
public class SignData implements Serializable {
private byte[] pdfData;
private byte[] signImg;
private int areaId;
private Date signDate;
private String description;
private String numser;
private boolean signed;
private String signGuid;
private boolean signSuccess;
public byte[] getPdfData() {
return pdfData;
}
public void setPdfData(byte[] pdfData) {
this.pdfData = pdfData;
}
public Date getSignDate() {
return signDate;
}
public void setSignDate(Date signDate) {
this.signDate = signDate;
}
public String getNumser() {
return numser;
}
public void setNumser(String numser) {
this.numser = numser;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isSigned() {
return signed;
}
public void setSigned(boolean signed) {
this.signed = signed;
}
public String getSignGuid() {
return signGuid;
}
public void setSignGuid(String signGuid) {
this.signGuid = signGuid;
}
public boolean isSignSuccess() {
return signSuccess;
}
public void setSignSuccess(boolean signSuccess) {
this.signSuccess = signSuccess;
}
public byte[] getSignImg() {
return signImg;
}
public void setSignImg(byte[] signImg) {
this.signImg = signImg;
}
public int getAreaId() {
return areaId;
}
public void setAreaId(int areaId) {
this.areaId = areaId;
}
}

@ -0,0 +1,28 @@
package info.bukova.isspst.signapi;
import java.io.Serializable;
/**
* @author Pepa Rokos
*/
public class SignUploadResponse implements Serializable {
private boolean ok;
private String errorMessage;
public boolean isOk() {
return ok;
}
public void setOk(boolean ok) {
this.ok = ok;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}

@ -0,0 +1,148 @@
package info.bukova.isspst.signapi;
import info.bukova.isspst.Constants;
import info.bukova.isspst.SessionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @author Pepa Rokos
*/
@Controller
public class SigningController {
@Autowired
private SessionData sessionData;
@Autowired
private JnlpGenerator jnlpGenerator;
@Autowired
private ServletContext context;
@RequestMapping(value="/sign/data", method= RequestMethod.GET)
public void dataForSign(HttpServletResponse response, HttpServletRequest request) {
SignData data = (SignData) sessionData.getProperty(Constants.KEY_SIGN_DATA);
ObjectOutputStream os = null;
try {
os = new ObjectOutputStream(response.getOutputStream());
response.setContentType("application/x-java-serialized-object");
os.writeObject(data);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@RequestMapping(value="/sign/data", method= RequestMethod.POST)
public void signedData(HttpServletRequest request, HttpServletResponse response) {
ObjectInputStream ois = null;
ObjectOutputStream os = null;
String error = null;
try {
ois = new ObjectInputStream(request.getInputStream());
SignData data = (SignData) ois.readObject();
sessionData.setProperty(Constants.KEY_SIGN_DATA, data);
} catch (IOException e) {
e.printStackTrace();
error = "IO error";
} catch (ClassNotFoundException e) {
e.printStackTrace();
error = "Loading error";
}
try {
SignUploadResponse resp = new SignUploadResponse();
if (error == null) {
resp.setOk(true);
} else {
resp.setOk(false);
resp.setErrorMessage(error);
}
os = new ObjectOutputStream(response.getOutputStream());
response.setContentType("application/x-java-serialized-object");
os.writeObject(resp);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping(value="/sign/signer.jnlp", method= RequestMethod.GET)
public void jnlp(HttpServletResponse response) {
byte[] data = jnlpGenerator.generate();
sendByte(response, data, "application/x-java-jnlp-file");
}
@RequestMapping(value="/sign/pdfsigner.jar", method= RequestMethod.GET)
public void pdfsigner(HttpServletResponse response) {
sendJar(response, "Linux");
}
@RequestMapping(value="/sign/pdfsignerWin.jar", method= RequestMethod.GET)
public void pdfsignerWin(HttpServletResponse response) {
sendJar(response, "Windows");
}
private void sendJar(HttpServletResponse response, String os) {
File inputJar;
if (os.startsWith("Windows")) {
inputJar = new File(context.getRealPath("/WEB-INF/signer/PDFSignerWin.jar"));
} else {
inputJar = new File(context.getRealPath("/WEB-INF/signer/PDFSigner.jar"));
}
try {
byte[] data = new byte[(int) inputJar.length()];
FileInputStream is = new FileInputStream(inputJar);
is.read(data);
sendByte(response, data, "application/java-archive");
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendByte(HttpServletResponse response, byte[] data, String contentType) {
ServletOutputStream os = null;
try {
os = response.getOutputStream();
response.setContentType(contentType);
response.setContentLength(data.length);
os.write(data);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

@ -1,13 +1,170 @@
package info.bukova.isspst.sort;
import org.zkoss.zul.Listheader;
import info.bukova.isspst.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zul.*;
import java.io.ByteArrayOutputStream;
import java.util.List;
@SuppressWarnings("serial")
public class CzechSortListheader extends Listheader {
static {
addClientEvent(CzechSortListheader.class, Events.ON_RIGHT_CLICK, CE_IMPORTANT | CE_NON_DEFERRABLE);
}
public void onRightClick() {
Menupopup popup = new Menupopup();
popup.setPage(this.getPage());
popup.setWidth("250px");
this.setContext(popup);
Menuitem item = new Menuitem();
item.setLabel(StringUtils.localize("ExportToExcel"));
item.setImage("/img/excel-032.png");
item.setParent(popup);
item.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(org.zkoss.zk.ui.event.Event event) throws Exception {
Listbox listBox = getListbox();
if (listBox != null) {
HSSFWorkbook workBook = new HSSFWorkbook();
HSSFSheet workSheet = workBook.createSheet("export");
int rowNumber = 0;
Row excelRow = null;
Cell excelCell = null;
HSSFCellStyle cellStyle = workBook.createCellStyle();
HSSFFont defaultFont = cellStyle.getFont(workBook);
HSSFCellStyle cellStyleNumber = workBook.createCellStyle();
cellStyleNumber.setAlignment(CellStyle.ALIGN_RIGHT);
//http://www.roseindia.net/java/poi/setdataformat.shtml
//HSSFDataFormat dataNumberFormat = workBook.createDataFormat();
//cellStyleNumber.setDataFormat(dataNumberFormat.getFormat("# ##0,00"));
cellStyleNumber.setDataFormat((short)4);
HSSFCellStyle cellStyleDate = workBook.createCellStyle();
cellStyleDate.setAlignment(CellStyle.ALIGN_RIGHT);
//http://www.roseindia.net/java/poi/setdataformat.shtml
HSSFDataFormat dataDateFormat = workBook.createDataFormat();
cellStyleDate.setDataFormat(dataDateFormat.getFormat("DD. MM. YYYY"));
//cellStyleDate.setDataFormat((short) 15);
int totalCols = 0;
Listhead listHead = listBox.getListhead();
if (listHead != null) {
HSSFCellStyle cellStyleHeader = workBook.createCellStyle();
cellStyleHeader.setAlignment(CellStyle.ALIGN_CENTER);
HSSFFont font = workBook.createFont();
font.setFontName(defaultFont.getFontName());
font.setFontHeightInPoints(defaultFont.getFontHeightInPoints());
font.setBold(true);
cellStyleHeader.setFont(font);
excelRow = workSheet.createRow(rowNumber++);
List<Listheader> headerList = listHead.getChildren();
totalCols = headerList.size();
for (int i = 0; i < totalCols; i++) {
Listheader listHeader = headerList.get(i);
String label = listHeader.getLabel();
excelCell = excelRow.createCell(i);
excelCell.setCellStyle(cellStyleHeader);
excelCell.setCellValue(label);
}
}
List<Listitem> itemList = listBox.getItems();
for (int i = 0; i < itemList.size(); i++) {
Listitem item = itemList.get(i);
excelRow = workSheet.createRow(rowNumber++);
List<Listcell> cellList = item.getChildren();
for (int k=0; k < cellList.size(); k++) {
Listcell cell = cellList.get(k);
String label = cell.getLabel();
HSSFCellStyle cellStyleActual = cellStyle;
excelCell = excelRow.createCell(k);
if (label != null) {
if (label.isEmpty()) {
//List<Component> componentList = cell.getChildren();
Component component = cell.getFirstChild();
if (component != null) {
if (component instanceof Textbox) {
Textbox textBox = (Textbox) component;
label = textBox.getValue();
}
else if (component instanceof Button) {
Button button = (Button) component;
label = button.getLabel();
}
}
}
if (label.matches("^[+-]?[0-9]{1,3}(,?[0-9]{3})*(\\.[0-9]+)?$")) {
// english number -1,234.56 (change browser language)
label = label.replace(",", " ");
label = label.replace(".", ",");
}
if (label.matches("^[+-]?[0-9]{1,3}([ \\xA0][0-9]{3})*([,][0-9]+)?$")) {
// czech number -1 234,56
cellStyleActual = cellStyleNumber;
}
else if (label.matches("[0-9]{1,2}[.][ \\xA0]?[0-9]{1,2}[.][ \\xA0]?[0-9]{4}")) {
// czech date
cellStyleActual = cellStyleDate;
}
}
excelCell.setCellStyle(cellStyleActual);
excelCell.setCellValue(label);
}
}
for (int i = 0; i < totalCols; i++) {
//int width = workSheet.getColumnWidth(i);
workSheet.autoSizeColumn(i);
int width = workSheet.getColumnWidth(i);
int maxWidth = 8000;
if (width > maxWidth) {
workSheet.setColumnWidth(i, maxWidth);
}
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
workBook.write(os);
Filedownload.save(os.toByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "temp" + Long.toString(System.nanoTime()) + ".xlsx");
// //Filedownload.save(tempFile, "application/vnd.ms-excel");
}
}
});
}
@Override
public void service(AuRequest request, boolean everError) {
super.service(request, everError);
}
@Override
public void setSort(String type) {
if (type.startsWith("czech"))
{
// czech(propertyName)
@ -21,5 +178,4 @@ public class CzechSortListheader extends Listheader {
super.setSort(type);
}
}
}

@ -19,9 +19,9 @@ public abstract class AbstractFileStorage<T> implements FileStorage<T> {
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new StorageException("File cannot be found: " + file.getName(), e.getCause());
} catch (IOException e) {
e.printStackTrace();
throw new StorageException("Cannot write file: " + file.getName(), e.getCause());
} finally {
try {
if (os != null) {

@ -44,6 +44,11 @@ public class DocumentFileStorageImpl extends AbstractFileStorage<FileMetainfo> i
this.rootPath = rootPath;
}
@Override
public String getRootPath() {
return this.rootPath;
}
@Override
public void saveFile(byte[] data, FileMetainfo fileID) {
String fileName = generateFileName(fileID.getFileName());

@ -9,7 +9,7 @@ import java.io.File;
*/
public interface FileStorage<T> {
// public String getRootPath();
public String getRootPath();
public void saveFile(byte[] data, T fileID);
public void saveFile(File file, T fileId);
public void removeFile(T fileID);

@ -12,6 +12,11 @@ public class LocalFileStorage extends AbstractFileStorage<String> {
this.rootPath = rootPath;
}
@Override
public String getRootPath() {
return this.rootPath;
}
public void setContext(ServletContext ctx) {
this.context = ctx;
}

@ -0,0 +1,10 @@
package info.bukova.isspst.storage;
import info.bukova.isspst.data.SignedDocumentItem;
/**
* @author Pepa Rokos
*/
public interface ReportFileStorage extends FileStorage<SignedDocumentItem> {
}

@ -0,0 +1,80 @@
package info.bukova.isspst.storage;
import info.bukova.isspst.data.SignedDocumentItem;
import java.io.File;
import java.util.UUID;
/**
* @author Pepa Rokos
*/
public class ReportFileStorageImpl extends AbstractFileStorage<SignedDocumentItem> implements ReportFileStorage {
private String rootPath;
public void setRootPath(String rootPath) {
this.rootPath = rootPath;
}
@Override
public String getRootPath() {
return this.rootPath;
}
private String getFilePath(String fileName) {
return rootPath + "/" + fileName;
}
@Override
public void saveFile(byte[] data, SignedDocumentItem signedDocumentItem) {
String fileName = signedDocumentItem.getFileName();
if (fileName == null) {
fileName = UUID.randomUUID().toString() + ".pdf";
}
saveFileDataToPath(data, getFilePath(fileName));
signedDocumentItem.setFileName(fileName);
}
@Override
public void saveFile(File file, SignedDocumentItem fileId) {
throw new UnsupportedOperationException();
}
@Override
public void removeFile(SignedDocumentItem signedDocumentItem) {
removeFileByPath(getFilePath(signedDocumentItem.getFileName()));
}
@Override
public void moveFile(String source, String destination) {
throw new UnsupportedOperationException();
}
@Override
public void createDirectory(String dir) {
throw new UnsupportedOperationException();
}
@Override
public byte[] fileData(SignedDocumentItem signedDocumentItem) {
return fileDataFromPath(getFilePath(signedDocumentItem.getFileName()));
}
@Override
public File file(SignedDocumentItem signedDocumentItem) {
return null;
}
@Override
public boolean dirExists(String path) {
return false;
}
@Override
public String serverPath(SignedDocumentItem signedDocumentItem) {
return null;
}
}

@ -0,0 +1,69 @@
package info.bukova.isspst.ui;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.Converter;
import org.zkoss.util.Locales;
import org.zkoss.zk.ui.Component;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Locale;
public class BigDecimalFilterConverter implements Converter<String, BigDecimal, Component>
{
private final static Logger log = LoggerFactory.getLogger(BigDecimalFilterConverter.class.getName());
@Override
public BigDecimal coerceToBean(String str, Component component, BindContext cx)
{
// BigDecimal val = BigDecimal.ZERO;
BigDecimal val = null;
if (str != null)
{
try
{
Locale loc = Locales.getCurrent();
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(loc);
format.setParseBigDecimal(true);
val = (BigDecimal) format.parse(str);
}
catch (NumberFormatException e)
{
log.warn(str, e);
}
catch (ParseException e)
{
log.warn(str, e);
}
}
return val;
}
@Override
public String coerceToUi(BigDecimal val, Component component, BindContext cx)
{
Locale loc = Locales.getCurrent();
if (val == null)
{
return "";
//val = BigDecimal.ZERO;
}
val = val.setScale(2, BigDecimal.ROUND_DOWN);
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(loc);
format.setMaximumFractionDigits(2);
format.setMinimumFractionDigits(0);
format.setGroupingUsed(true);
format.setGroupingSize(3);
String formatted = format.format(val);
return formatted;
}
}

@ -0,0 +1,19 @@
package info.bukova.isspst.ui;
import org.zkoss.bind.annotation.Init;
public class BindingViewModel<T> extends DocumentViewModel {
private BindingForm<T> dataForm;
@Init
public void initBindingViewModel() {
super.initDocumentViewModel();
dataForm = new BindingForm<T>();
}
public BindingForm<T> getDataForm() {
return this.dataForm;
}
}

@ -16,6 +16,18 @@ import org.zkoss.zul.Messagebox;
public class DocumentViewModel
{
protected BigDecimalFilterConverter standardBigDecimalFilterConverter;
public BigDecimalFilterConverter getStandardBigDecimalFilterConverter()
{
return standardBigDecimalFilterConverter;
}
public void setStandardBigDecimalFilterConverter(BigDecimalFilterConverter standardBigDecimalFilterConverter)
{
this.standardBigDecimalFilterConverter = standardBigDecimalFilterConverter;
}
protected BigDecimalConverter standardBigDecimalConverter;
protected BoolConverter standardBoolConverter;
@ -53,6 +65,7 @@ public class DocumentViewModel
@Init
public void initDocumentViewModel()
{
this.standardBigDecimalFilterConverter = new BigDecimalFilterConverter();
this.standardBigDecimalConverter = new BigDecimalConverter();
this.standardBoolConverter = new BoolConverter();
}

@ -5,10 +5,6 @@ import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.services.IsspstException;
import info.bukova.isspst.services.Service;
import info.bukova.isspst.services.ValidationException;
import java.sql.SQLException;
import java.util.Map;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.AccessDeniedException;
@ -20,28 +16,29 @@ import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;
public class FormViewModel<T extends DataModel> extends DocumentViewModel
{
import java.sql.SQLException;
import java.util.Map;
public class FormViewModel<T extends DataModel> extends BindingViewModel<T>
{
private T dataBean;
private Map<String, String> errMessages;
private Service<T> service;
private boolean newRec;
protected boolean newRec;
private ServiceConstraint<T> constraint;
private BindingForm<T> dataForm;
@Init
public void initFormViewModel(@ExecutionArgParam("selected") T selected, @ExecutionArgParam("service") Service<T> service)
{
super.initDocumentViewModel();
super.initBindingViewModel();
this.dataBean = selected;
this.service = service;
constraint = new ServiceConstraint<T>();
constraint.setDataBean(selected);
constraint.setService(service);
dataForm = new BindingForm<T>();
dataForm.setDataBean(selected);
this.getDataForm().setDataBean(selected);
if (selected.getId() == 0 && selected.getCreated() == null)
{
@ -186,9 +183,4 @@ public class FormViewModel<T extends DataModel> extends DocumentViewModel
{
return true;
}
public BindingForm<T> getDataForm() {
return dataForm;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save