diff --git a/src/main/java/info/bukova/isspst/AppInitListener.java b/src/main/java/info/bukova/isspst/AppInitListener.java index 2daddb32..3a9c284f 100644 --- a/src/main/java/info/bukova/isspst/AppInitListener.java +++ b/src/main/java/info/bukova/isspst/AppInitListener.java @@ -3,11 +3,13 @@ package info.bukova.isspst; import java.util.List; import info.bukova.isspst.data.Permission; +import info.bukova.isspst.data.RequirementType; import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; import info.bukova.isspst.reporting.Report; import info.bukova.isspst.reporting.ReportMapping; import info.bukova.isspst.reporting.ReportType; +import info.bukova.isspst.services.requirements.RequirementTypeService; import info.bukova.isspst.services.users.PermissionService; import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.UserService; @@ -26,6 +28,7 @@ public class AppInitListener implements ServletContextListener { private RoleService roleService; private UserService userService; private PermissionService permService; + private RequirementTypeService reqTypeService; @Override public void contextDestroyed(ServletContextEvent arg0) { @@ -41,12 +44,14 @@ public class AppInitListener implements ServletContextListener { roleService = ctx.getBean(RoleService.class); userService = ctx.getBean(UserService.class); permService = ctx.getBean(PermissionService.class); + reqTypeService = ctx.getBean(RequirementTypeService.class); userService.grantAdmin(); checkRoles(); checkUsers(); checkPermissions(); checkAllAdminRights(); + checkReqTypes(); userService.removeAccess(); loadModuleReports(); @@ -140,5 +145,14 @@ public class AppInitListener implements ServletContextListener { } } } + + private void checkReqTypes() { + List types = reqTypeService.getAll(); + for (RequirementType type : Constants.REQTYPES) { + if (!types.contains(type)) { + reqTypeService.add(type); + } + } + } } diff --git a/src/main/java/info/bukova/isspst/Constants.java b/src/main/java/info/bukova/isspst/Constants.java index f26b4369..92704251 100644 --- a/src/main/java/info/bukova/isspst/Constants.java +++ b/src/main/java/info/bukova/isspst/Constants.java @@ -2,6 +2,7 @@ package info.bukova.isspst; import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.PermissionType; +import info.bukova.isspst.data.RequirementType; import info.bukova.isspst.data.Role; import info.bukova.isspst.reporting.Report; import info.bukova.isspst.reporting.ReportMapping; @@ -9,6 +10,7 @@ import info.bukova.isspst.services.addressbook.AdbService; import info.bukova.isspst.services.buildings.BuildingService; import info.bukova.isspst.services.munits.MUnitService; import info.bukova.isspst.services.material.MaterialService; +import info.bukova.isspst.services.requirements.RequirementTypeService; import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.UserService; import info.bukova.isspst.services.workgroups.WorkgroupService; @@ -57,6 +59,7 @@ public class Constants { public final static String MOD_MATERIAL = "MATERIAL"; public final static String MOD_WORKGROUPS = "WORKGROUPS"; public final static String MOD_REQUIREMENTS = "REQUIREMENTS"; + public final static String MOD_WORKFLOW = "WORKFLOW"; public final static Module MODULES[] = { new Module(MOD_USERS, "Uživatelé", UserService.class), new Module(MOD_PERMISSIONS, "Práva", RoleService.class), @@ -65,13 +68,11 @@ public class Constants { new Module(MOD_MUNITS, "Měrné jednotky", MUnitService.class), new Module(MOD_MATERIAL, "Materiál", MaterialService.class), new Module(MOD_WORKGROUPS, "Pracovní skupiny", WorkgroupService.class), - new Module(MOD_REQUIREMENTS, "Požadavky", null) + new Module(MOD_REQUIREMENTS, "Požadavky", null), + new Module(MOD_WORKFLOW, "Procesy schválení", RequirementTypeService.class) }; - public final static String PERM_APPROVE_WORKGROUP = "PERM_APPROVE_WORKGROUP"; - public final static String PERM_APPROVE_CENTRE = "PERM_APPROVE_CENTRE"; - public final static String PERM_APPROVE_LIMIT = "PERM_APPROVE_LIMIT"; - public final static String PERM_APPROVE_FINAL = "PERM_APPROVE_FINAL"; + public final static String PERM_APPROVE = "PERM_APPROVE"; public final static String PERM_SHOW_WORKGROUP_REQ = "PERM_SHOW_WORKGROUP_REQ"; public final static String PERM_SHOW_CENTRE_REQ = "PERM_SHOW_CENTRE_REQ"; public final static String PERM_SHOW_ALL_REQ = "PERM_SHOW_ALL_REQ"; @@ -80,10 +81,7 @@ public class Constants { new Permission(PERM_SHOW_WORKGROUP_REQ, "Zobrazení požadavků komise", MOD_REQUIREMENTS, PermissionType.WORKGROUP), new Permission(PERM_SHOW_CENTRE_REQ, "Zobrazení požadavků střediska", MOD_REQUIREMENTS, PermissionType.CENTRE), new Permission(PERM_SHOW_ALL_REQ, "Zobrazení všech požadavků", MOD_REQUIREMENTS, PermissionType.GLOBAL), - new Permission(PERM_APPROVE_WORKGROUP, "Schválení v komisi", MOD_REQUIREMENTS, PermissionType.WORKGROUP), - new Permission(PERM_APPROVE_CENTRE, "Schválení ve středisku", MOD_REQUIREMENTS, PermissionType.CENTRE), - new Permission(PERM_APPROVE_LIMIT, "Schválení nadlimitních", MOD_REQUIREMENTS, PermissionType.GLOBAL), - new Permission(PERM_APPROVE_FINAL, "Konečné schválení", MOD_REQUIREMENTS, PermissionType.CENTRE), + new Permission(PERM_APPROVE, "Schválení", MOD_REQUIREMENTS, PermissionType.WORKGROUP), }; public final static String DYNAMIC_REPORT_NAME = "Tabulková sestava"; @@ -91,4 +89,11 @@ public class Constants { new ReportMapping(MOD_ADDRESSBOOK, new Report("Adresní karty", "address")), new ReportMapping(MOD_ADDRESSBOOK, new Report("Adresna", "address", false, true)) }; + + public final static String REQTYPE_ORDER = "ORDER"; + public final static String REQTYPE_BUSINESSTRIP = "BUSINESSTRIP"; + public final static RequirementType REQTYPES[] = { + new RequirementType(REQTYPE_ORDER, "Objednávky materiálu a služeb"), + new RequirementType(REQTYPE_BUSINESSTRIP, "Služební cesty") + }; } diff --git a/src/main/java/info/bukova/isspst/dao/RequirementTypeDao.java b/src/main/java/info/bukova/isspst/dao/RequirementTypeDao.java new file mode 100644 index 00000000..aee8f9b8 --- /dev/null +++ b/src/main/java/info/bukova/isspst/dao/RequirementTypeDao.java @@ -0,0 +1,7 @@ +package info.bukova.isspst.dao; + +import info.bukova.isspst.data.RequirementType; + +public interface RequirementTypeDao extends BaseDao { + +} diff --git a/src/main/java/info/bukova/isspst/dao/jpa/RequirementTypeDaoJPA.java b/src/main/java/info/bukova/isspst/dao/jpa/RequirementTypeDaoJPA.java new file mode 100644 index 00000000..d8202e8a --- /dev/null +++ b/src/main/java/info/bukova/isspst/dao/jpa/RequirementTypeDaoJPA.java @@ -0,0 +1,8 @@ +package info.bukova.isspst.dao.jpa; + +import info.bukova.isspst.dao.RequirementTypeDao; +import info.bukova.isspst.data.RequirementType; + +public class RequirementTypeDaoJPA extends BaseDaoJPA implements RequirementTypeDao { + +} diff --git a/src/main/java/info/bukova/isspst/data/RequirementType.java b/src/main/java/info/bukova/isspst/data/RequirementType.java new file mode 100644 index 00000000..f2d1b9fd --- /dev/null +++ b/src/main/java/info/bukova/isspst/data/RequirementType.java @@ -0,0 +1,71 @@ +package info.bukova.isspst.data; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.persistence.Table; + +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; + +@Entity +@Table(name = "REQUIREMENTTYPE") +public class RequirementType extends BaseData { + + @Column(name = "TYPE") + private String type; + @Column(name = "DESCRIPTION") + private String description; + @OneToMany(cascade = CascadeType.ALL) + @LazyCollection(LazyCollectionOption.FALSE) + @OrderBy("WORDER") + private List workflow; + + public RequirementType() { + workflow = new ArrayList(); + } + + public RequirementType(String type, String description) { + this(); + this.type = type; + this.description = description; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getWorkflow() { + return workflow; + } + + public void setWorkflow(List workflow) { + this.workflow = workflow; + } + + public boolean equals(Object o) { + if (o instanceof RequirementType && ((RequirementType)o).getType().equals(this.type)) { + return true; + } + + return false; + } + +} diff --git a/src/main/java/info/bukova/isspst/data/Workflow.java b/src/main/java/info/bukova/isspst/data/Workflow.java new file mode 100644 index 00000000..a5d839cd --- /dev/null +++ b/src/main/java/info/bukova/isspst/data/Workflow.java @@ -0,0 +1,59 @@ +package info.bukova.isspst.data; + +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; + +@Entity +@Table(name = "WORKFLOW") +public class Workflow extends BaseData { + + @Column(name = "CENTRE") + private Boolean centre; + @ManyToOne + @LazyCollection(LazyCollectionOption.FALSE) + @JoinColumn(name = "ROLE_ID") + private Role role; + @Column(name = "WORDER") + private Integer wOrder; + + public Boolean getCentre() { + return centre; + } + + public void setCentre(Boolean centre) { + this.centre = centre; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public boolean equals(Object o) { + if (o instanceof Workflow + && ((Workflow)o).getCentre().equals(centre) + && ((Workflow)o).getRole().equals(role)) { + return true; + } + + return false; + } + + public Integer getOrder() { + return wOrder; + } + + public void setOrder(Integer order) { + this.wOrder = order; + } + +} diff --git a/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeService.java b/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeService.java new file mode 100644 index 00000000..53727d34 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeService.java @@ -0,0 +1,8 @@ +package info.bukova.isspst.services.requirements; + +import info.bukova.isspst.data.RequirementType; +import info.bukova.isspst.services.Service; + +public interface RequirementTypeService extends Service { + +} diff --git a/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeServiceImpl.java b/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeServiceImpl.java new file mode 100644 index 00000000..276d8917 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/requirements/RequirementTypeServiceImpl.java @@ -0,0 +1,8 @@ +package info.bukova.isspst.services.requirements; + +import info.bukova.isspst.data.RequirementType; +import info.bukova.isspst.services.AbstractOwnedService; + +public class RequirementTypeServiceImpl extends AbstractOwnedService implements RequirementTypeService { + +} diff --git a/src/main/java/info/bukova/isspst/services/users/RoleService.java b/src/main/java/info/bukova/isspst/services/users/RoleService.java index e4c8f274..ea5d1d65 100644 --- a/src/main/java/info/bukova/isspst/services/users/RoleService.java +++ b/src/main/java/info/bukova/isspst/services/users/RoleService.java @@ -2,6 +2,7 @@ package info.bukova.isspst.services.users; import java.util.List; +import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Role; import info.bukova.isspst.services.Service; @@ -10,5 +11,7 @@ public interface RoleService extends Service { public Role getRoleByAuthority(String authority); public List getWorkgroupRoles(); public List getCentreRoles(); + public List getRolesWithPermission(Permission perm, boolean centre); + public List getRolesWithPermission(String authority, boolean centre); } diff --git a/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java b/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java index df31aa6d..684ff97d 100644 --- a/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java +++ b/src/main/java/info/bukova/isspst/services/users/RoleServiceImpl.java @@ -1,13 +1,21 @@ package info.bukova.isspst.services.users; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.hibernate.Query; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Role; import info.bukova.isspst.services.AbstractService; public class RoleServiceImpl extends AbstractService implements RoleService { + + @Autowired + private PermissionService permService; @Override @Transactional @@ -27,4 +35,28 @@ public class RoleServiceImpl extends AbstractService implements RoleServic return this.execQuery("from Role where centre = true"); } + @SuppressWarnings("unchecked") + @Override + @Transactional + public List getRolesWithPermission(Permission perm, boolean centre) { + String wgClausule; + if (centre) { + wgClausule = "centre"; + } else { + wgClausule = "workgroup"; + } + Set perms = new HashSet(); + perms.add(perm); + Query q = dao.getQuery("select r from Role r join r.permissions p where r." + wgClausule + " = true and p in (:perms)"); + q.setParameterList("perms", perms); + return q.list(); + } + + @Override + @Transactional + public List getRolesWithPermission(String authority, boolean centre) { + Permission p = permService.selectSingle("from Permission where authority = '" + authority + "'"); + return getRolesWithPermission(p, centre); + } + } diff --git a/src/main/java/info/bukova/isspst/ui/requirements/RequirementTypesVM.java b/src/main/java/info/bukova/isspst/ui/requirements/RequirementTypesVM.java new file mode 100644 index 00000000..0b6807a9 --- /dev/null +++ b/src/main/java/info/bukova/isspst/ui/requirements/RequirementTypesVM.java @@ -0,0 +1,203 @@ +package info.bukova.isspst.ui.requirements; + +import info.bukova.isspst.Constants; +import info.bukova.isspst.data.RequirementType; +import info.bukova.isspst.data.Role; +import info.bukova.isspst.data.Workflow; +import info.bukova.isspst.services.requirements.RequirementTypeService; +import info.bukova.isspst.services.users.RoleService; + +import java.util.ArrayList; +import java.util.List; + +import org.zkoss.bind.annotation.BindingParam; +import org.zkoss.bind.annotation.Command; +import org.zkoss.bind.annotation.Init; +import org.zkoss.bind.annotation.NotifyChange; +import org.zkoss.zk.ui.event.DropEvent; +import org.zkoss.zk.ui.select.annotation.WireVariable; +import org.zkoss.zul.Listitem; + +public class RequirementTypesVM { + + @WireVariable + private RequirementTypeService reqTypeService; + @WireVariable + private RoleService roleService; + private List reqTypes; + private List centreRoles; + private List workgroupRoles; + private RequirementType selected; + + @Init + public void init() { + reqTypes = reqTypeService.getAll(); + initRoles(); + } + + private void initRoles() { + centreRoles = new ArrayList(roleService.getRolesWithPermission(Constants.PERM_APPROVE, true)); + workgroupRoles = new ArrayList(roleService.getRolesWithPermission(Constants.PERM_APPROVE, false)); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void addRoleWg(@BindingParam("event") DropEvent event) { + Role r; + try { + r = ((Listitem)event.getDragged()).getValue(); + } catch (ClassCastException e) { + return; + } + addRole(r, false); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void addRoleCentre(@BindingParam("event") DropEvent event) { + Role r; + try { + r = ((Listitem)event.getDragged()).getValue(); + } catch (ClassCastException e) { + return; + } + addRole(r, true); + } + + private void addRole(Role r, boolean centre) { + Workflow w = new Workflow(); + w.setRole(r); + w.setCentre(centre); + w.setOrder(selected.getWorkflow().size()); + + if (!selected.getWorkflow().contains(w)) { + selected.getWorkflow().add(w); + } + + if (centre) { + centreRoles.remove(r); + } else { + workgroupRoles.remove(r); + } + + reqTypeService.update(selected); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void removeRoleWg(@BindingParam("event") DropEvent event) { + removeWorkflow((Workflow) ((Listitem)event.getDragged()).getValue()); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void removeRoleCentre(@BindingParam("event") DropEvent event) { + removeWorkflow((Workflow) ((Listitem)event.getDragged()).getValue()); + } + + private void removeWorkflow(Workflow w) { + selected.getWorkflow().remove(w); + + if (w.getCentre()) { + centreRoles.add(w.getRole()); + } else { + workgroupRoles.add(w.getRole()); + } + + resetOrder(); + + reqTypeService.update(selected); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void reorderWg(@BindingParam("event") DropEvent event) { + reorder(event, false); + } + + @Command + @NotifyChange({"selected", "centreRoles", "workgroupRoles"}) + public void reorderCentre(@BindingParam("event") DropEvent event) { + reorder(event, true); + } + + private void reorder(DropEvent event, boolean centre) { + Workflow w; + + try { + w = ((Listitem)event.getDragged()).getValue(); + } catch (ClassCastException e) { + if (centre) { + addRoleCentre(event); + } else { + addRoleWg(event); + } + return; + } + + Workflow target = ((Listitem)event.getTarget()).getValue(); + List wf = selected.getWorkflow(); + int dragIndex = wf.indexOf(w); + int dropIndex = wf.indexOf(target); + + if (dragIndex > dropIndex) { + wf.remove(w); + wf.add(dropIndex, w); + } else { + for (int i = dragIndex; i < dropIndex; i++) { + wf.add(i, wf.get(i + 1)); + } + + wf.remove(w); + wf.remove(dropIndex); + wf.add(dropIndex, w); + } + + w.setOrder(wf.indexOf(w)); + resetOrder(); + + reqTypeService.update(selected); + } + + private void resetOrder() { + for (int i = 0; i < selected.getWorkflow().size(); i++) { + selected.getWorkflow().get(i).setOrder(i); + } + } + + public List getReqTypes() { + return reqTypes; + } + + public List getCentreRoles() { + return centreRoles; + } + + public List getWorkgroupRoles() { + return workgroupRoles; + } + + public RequirementType getSelected() { + return selected; + } + + @NotifyChange({"selected", "workgroupRoles", "centreRoles"}) + public void setSelected(RequirementType selected) { + if (selected == null) { + return; + } + + initRoles(); + + for (Workflow w : selected.getWorkflow()) { + if (w.getCentre()) { + centreRoles.remove(w.getRole()); + } else { + workgroupRoles.remove(w.getRole()); + } + } + + this.selected = selected; + } + +} diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index 3c62d43a..0ef3d846 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -16,6 +16,8 @@ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/locales/zk-label.properties b/src/main/webapp/WEB-INF/locales/zk-label.properties index 2d0850ab..ab3ead0b 100644 --- a/src/main/webapp/WEB-INF/locales/zk-label.properties +++ b/src/main/webapp/WEB-INF/locales/zk-label.properties @@ -38,6 +38,8 @@ AgendaRights=Práva RightsFormTitle=Práva RightsGridRole=Role RightsGridModules=Práva modulů +WorkgroupFunction=Funkce v komisích +CentreFunction=Funkce ve střediscích AgendaSuppliers=Dodavatelé SuppliersFormTitle=Dodavatel @@ -90,6 +92,15 @@ MaterialFormTitle=Materiál AgendaWorkgroups=Střediska / komise WorkgroupFormTitle=Pracvní skupina +AgendaWorkflow=Procesy schválení +RequirementType=Typ požadavku: +AvailableRoles=Dostupné role +WorkgroupRoles=Role komisí +CentreRoles=Role středisek +Workflow=Proces schválení +WorkgroupWorkflow=Schválení v komisi +CentreWorkflow=Schválení ve středisku + CentresForRequirements=Střediska, pro která lze vkládat požadavky WorkgroupMembership=Členství v komisích LogedInUser=Přihlášený uživatel: diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml index 6ef6e9ad..39ab5cdc 100644 --- a/src/main/webapp/WEB-INF/spring/root-context.xml +++ b/src/main/webapp/WEB-INF/spring/root-context.xml @@ -128,6 +128,10 @@ + + + + @@ -189,5 +193,10 @@ + + + + + diff --git a/src/main/webapp/admin/permissions/permForm.zul b/src/main/webapp/admin/permissions/permForm.zul index 6e340195..da5fa53c 100644 --- a/src/main/webapp/admin/permissions/permForm.zul +++ b/src/main/webapp/admin/permissions/permForm.zul @@ -5,8 +5,8 @@