Merge pull request #35 from dgray16/master

Limits functionality to master
This commit is contained in:
Jeroen Baten 2015-12-22 17:11:42 +01:00
commit 318f674c01
37 changed files with 573 additions and 105 deletions

View file

@ -228,8 +228,6 @@ Microsoft Windows
# Copy downloaded *.jar file to JAVA_HOME location: (e.g. C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext)
# Put downloaded *.jar file to Tomcat lib location: (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib)
* Download latest ``.war`` file from SourceForge.net (for PostgreSQL) and rename it to libreplan.war::
# http://sourceforge.net/projects/libreplan/files/LibrePlan/
* Create database::
@ -266,15 +264,12 @@ Microsoft Windows
GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan;
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup::
* Create an Environment Variable JAVA_HOME
# You need to set it to your JDK installed directory
* Configure Apache Tomcat Server
# Put your libreplan.war file to Apache Tomcat webapps folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\)
# Go to (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\Catalina\localhost\) and create there libreplan.xml file with this lines of code:
<?xml version="1.0" encoding="UTF-8"?>
@ -288,13 +283,7 @@ Microsoft Windows
url="jdbc:postgresql://localhost/libreplan" />
</Context>
* Start Apache Tomcat server
# Possible location: C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\Tomcat6.exe
* Go to http://localhost:8080/libreplan
=======
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup
* Download source code::
@ -316,8 +305,12 @@ Microsoft Windows
* Launch application::
# cd libreplan-webapp
# mvn jetty:run
* Get *.war file from project folder (e.g ../libreplan/libreplan-webapp/target/libreplan-webapp.war)
* Rename it to libreplan.war
* Put your libreplan.war file to Apache Tomcat webapps folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\)
* Start Apache Tomcat server
# Possible location: C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\Tomcat6.exe
* Go to http://localhost:8080/libreplan-webapp/

View file

@ -326,7 +326,7 @@ Microsoft Windows
Instructions:
* Download and install latest Java Runtime Environment 7u79 (JRE7u79)::
* Download and install latest Java Runtime Environment 7u80 (JRE7u79)::
# http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html
@ -367,7 +367,7 @@ Instructions:
ON ALL TABLES IN SCHEMA public
TO libreplan;
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup::
* Restore PostgreSQL / MySQL dump::
* Create an Environment Variable JRE_HOME

View file

@ -0,0 +1,39 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2015 LibrePlan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.common.daos;
import org.libreplan.business.common.entities.Limits;
import java.util.List;
/**
* DAO interface for the <code>Limits</code> entity.
* Contract for {@link LimitsDAO}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.2015.
*/
public interface ILimitsDAO extends IGenericDAO<Limits, Long> {
List<Limits> getAll();
Limits getUsersType();
Limits getResourcesType();
}

View file

@ -0,0 +1,58 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2015 LibrePlan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.common.daos;
import org.libreplan.business.common.entities.Limits;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* DAO for {@link Limits}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 24.09.15.
*/
@Repository
public class LimitsDAO extends GenericDAOHibernate<Limits, Long> implements ILimitsDAO {
@Override
public List<Limits> getAll() {
return list(Limits.class);
}
@Override
public Limits getUsersType() {
List<Limits> list = list(Limits.class);
for (Limits item : list)
if (item.getType().equals("users")) return item;
return null;
}
@Override
public Limits getResourcesType() {
List<Limits> list = list(Limits.class);
for (Limits item : list)
if (item.getType().equals("workers+machines")) return item;
return null;
}
}

View file

@ -0,0 +1,53 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2015 LibrePlan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.common.entities;
import org.libreplan.business.common.BaseEntity;
/**
* Limits entity, represents a limits for any functionality.
* This class is intended to work as a Hibernate component.
* It represents the limit that can be modified only in database.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.2015.
*/
public class Limits extends BaseEntity{
private String type;
private Integer value;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}

View file

@ -30,7 +30,7 @@ import java.util.List;
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 24.09.15.
* on 24.09.2015.
*/
@Repository
public class EmailTemplateDAO extends GenericDAOHibernate<EmailTemplate, Long> implements IEmailTemplateDAO{

View file

@ -30,7 +30,7 @@ import java.util.List;
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 29.09.15.
* on 29.09.2015.
*/
public interface IEmailTemplateDAO extends IGenericDAO<EmailTemplate, Long>{

View file

@ -29,7 +29,7 @@ import org.libreplan.business.settings.entities.Language;
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 29.09.15.
* on 29.09.2015.
*/
public class EmailTemplate extends BaseEntity {

View file

@ -120,4 +120,6 @@ public interface IResourceDAO extends IIntegrationEntityDAO<Resource> {
*/
List<HoursWorkedPerWorkerInAMonthDTO> getWorkingHoursPerWorker(Integer year, Integer month);
Number getRowCount();
}

View file

@ -36,7 +36,6 @@ import org.springframework.transaction.annotation.Transactional;
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> {

View file

@ -23,6 +23,7 @@ package org.libreplan.business.resources.daos;
import java.util.List;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.IntegrationEntityDAO;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;

View file

@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.IntegrationEntityDAO;
import org.libreplan.business.labels.entities.Label;
@ -248,6 +249,11 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
return result;
}
@Override
public Number getRowCount() {
return (Number) getSession().createCriteria(Resource.class).setProjection(Projections.rowCount()).uniqueResult();
}
private List<HoursWorkedPerWorkerInAMonthDTO> toDTO(List<Object> rows) {
List<HoursWorkedPerWorkerInAMonthDTO> result = new ArrayList<HoursWorkedPerWorkerInAMonthDTO>();

View file

@ -26,6 +26,7 @@ import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.IntegrationEntityDAO;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@ -43,7 +44,6 @@ import org.springframework.transaction.annotation.Transactional;
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
@ -198,5 +198,4 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
criteria.add(Restrictions.isNotNull("user"));
return criteria.list();
}
}

View file

@ -35,6 +35,7 @@ import org.libreplan.business.users.entities.User;
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
public interface IUserDAO extends IGenericDAO<User, Long>{
@ -102,4 +103,5 @@ public interface IUserDAO extends IGenericDAO<User, Long>{
List<User> findAll();
Number getRowCount();
}

View file

@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
@ -44,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@Repository
public class UserDAO extends GenericDAOHibernate<User, Long>
@ -179,4 +181,8 @@ public class UserDAO extends GenericDAOHibernate<User, Long>
return list(User.class);
}
@Override
public Number getRowCount() {
return (Number) getSession().createCriteria(User.class).setProjection(Projections.rowCount()).uniqueResult();
}
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<changeSet id="add-id_cost_category-column-to-criterion-table" author="ltilve">
@ -14,9 +14,9 @@
<changeSet id="add-id_cost_category-fk-to-criterion-table" author="ltilve">
<comment>Add foreign key constraint to new id_cost_category column on cost_category id</comment>
<addForeignKeyConstraint constraintName="cost_category_fkey"
baseTableName="criterion" baseColumnNames="id_cost_category"
referencedTableName="cost_category" referencedColumnNames="id"
onDelete="SET NULL" />
baseTableName="criterion" baseColumnNames="id_cost_category"
referencedTableName="cost_category" referencedColumnNames="id"
onDelete="SET NULL" />
</changeSet>
<changeSet id="add-new-column-automatic_budget_enabled" author="ltilve">
@ -25,11 +25,11 @@
<column name="automatic_budget_enabled" type="BOOLEAN" />
</addColumn>
<addDefaultValue tableName="configuration" columnName="automatic_budget_enabled"
defaultValueBoolean="FALSE" />
defaultValueBoolean="FALSE" />
<addNotNullConstraint tableName="configuration"
columnName="automatic_budget_enabled"
defaultNullValue="FALSE"
columnDataType="BOOLEAN" />
columnName="automatic_budget_enabled"
defaultNullValue="FALSE"
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="add-automatic_budget_type_of_work_hours-to-configuration" author="ltilve">
@ -41,8 +41,32 @@
<column name="automatic_budget_type_of_work_hours" type="BIGINT" />
</addColumn>
<addForeignKeyConstraint constraintName="automatic_budget_type_of_work_hours_fkey"
baseTableName="configuration" baseColumnNames="automatic_budget_type_of_work_hours"
referencedTableName="type_of_work_hours" referencedColumnNames="id" />
baseTableName="configuration" baseColumnNames="automatic_budget_type_of_work_hours"
referencedTableName="type_of_work_hours" referencedColumnNames="id" />
</changeSet>
<changeSet id="adding-limits" author="vova/jeroen">
<createTable tableName="limits">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" primaryKeyName="limits_pkey"/>
</column>
<column name="type" type="varchar(20)"/>
<column name="value" type="INTEGER"/>
</createTable>
<addUniqueConstraint
constraintName="type"
columnNames="type"
deferrable="false"
disabled="false"
initiallyDeferred="false"
tableName="limits"/>
<sql>
INSERT INTO limits VALUES(0, 'users', 5);
INSERT INTO limits VALUES(1, 'workers+machines', 10);
</sql>
</changeSet>
</databaseChangeLog>

View file

@ -100,6 +100,9 @@
<value>
org/libreplan/business/logs/entities/Logs.hbm.xml
</value>
<value>
org/libreplan/business/common/entities/Limits.hbm.xml
</value>
</list>
</property>
</bean>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.libreplan.business.email.entities" default-access="field">
<class name="org.libreplan.business.common.entities.Limits" abstract="true" table="limits">
<id name="id" access="property" type="long">
<generator class="hilo" >
<param name="max_lo">100</param>
</generator>
</id>
<property name="type" column="type"/>
<property name="value" column="value" type="long"/>
</class>
</hibernate-mapping>

View file

@ -93,7 +93,7 @@
</set>
<!-- Indexed on the other side -->
<set name="workReportLines" cascade="all-delete-orphan" inverse="true" batch-size="10">
<set name="workReportLines" cascade="all-delete-orphan" inverse="true" batch-size="10" fetch="join">
<key column="work_report_id"/>
<one-to-many class="WorkReportLine"/>
</set>

View file

@ -244,7 +244,8 @@ public class ConfigurationController extends GenericForwardComposer {
if ( getSelectedConnector() != null && getSelectedConnector().getName().equals("E-mail") &&
isEmailFieldsValid() == false ) {
messages.showMessage(Level.ERROR, _("Check username/password/sender fields"));
messages.showMessage(Level.ERROR, _("Check all fields"));
} else {
ConstraintChecker.isValid(configurationWindow);
if (checkValidEntitySequenceRows()) {
@ -1297,7 +1298,8 @@ public class ConfigurationController extends GenericForwardComposer {
key.equals(PredefinedConnectorProperties.JIRA_HOURS_TYPE) ||
key.equals(PredefinedConnectorProperties.HOST) ||
key.equals(PredefinedConnectorProperties.PORT) ||
key.equals(PredefinedConnectorProperties.EMAIL_SENDER) ) {
key.equals(PredefinedConnectorProperties.EMAIL_SENDER) ||
key.equals(PredefinedConnectorProperties.PROTOCOL) ) {
((InputElement) comp).setConstraint("no empty:"
+ _("cannot be empty"));
} else if ( key
@ -1326,14 +1328,15 @@ public class ConfigurationController extends GenericForwardComposer {
}
private boolean isEmailFieldsValid(){
if ( protocolsCombobox.getSelectedItem().getLabel().equals("STARTTLS") &&
emailUsernameTextbox.getValue() != null &&
emailPasswordTextbox.getValue() != null &&
emailUsernameTextbox.getValue().length() != 0 &&
emailPasswordTextbox.getValue().length() != 0 &&
emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") )
return true;
else return false;
if ( protocolsCombobox != null && protocolsCombobox.getSelectedItem() != null ){
if ( protocolsCombobox.getSelectedItem().getLabel().equals("STARTTLS") &&
emailUsernameTextbox.getValue() != null &&
emailPasswordTextbox.getValue() != null &&
emailUsernameTextbox.getValue().length() != 0 &&
emailPasswordTextbox.getValue().length() != 0 &&
emailSenderTextbox.getValue().matches("^\\S+@\\S+\\.\\S+$") )
return true;
}
return false;
}
}

View file

@ -0,0 +1,38 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2015 LibrePlan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.web.common;
import org.libreplan.business.common.entities.Limits;
import java.util.List;
/**
* Contract for {@link Limits}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.2015.
*/
public interface ILimitsModel {
List<Limits> getAll();
Limits getUsersType();
Limits getResourcesType();
}

View file

@ -0,0 +1,64 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2015 LibrePlan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.web.common;
import org.libreplan.business.common.daos.ILimitsDAO;
import org.libreplan.business.common.entities.Limits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Model for operations related to {@link Limits}.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 17.12.15.
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class LimitsModel implements ILimitsModel {
@Autowired
private ILimitsDAO limitsDAO;
@Override
@Transactional(readOnly = true)
public List<Limits> getAll() {
return limitsDAO.getAll();
}
@Override
@Transactional(readOnly = true)
public Limits getUsersType() {
return limitsDAO.getUsersType();
}
@Override
@Transactional(readOnly = true)
public Limits getResourcesType() {
return limitsDAO.getResourcesType();
}
}

View file

@ -32,7 +32,7 @@ import java.util.List;
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 28.09.15.
* on 28.09.2015.
*/
public interface IEmailTemplateModel {

View file

@ -34,7 +34,7 @@ import org.libreplan.business.resources.entities.Worker;
import org.libreplan.web.common.IIntegrationEntityModel;
import org.libreplan.web.resources.search.ResourcePredicate;
/*
/**
* This interface contains the operations to create/edit a machine.
*
* Conversation state: the Machine instance and associated entities.
@ -107,5 +107,4 @@ public interface IMachineModel extends IIntegrationEntityModel {
void confirmRemove(Machine machine) throws InstanceNotFoundException;
void removeCalendar();
}

View file

@ -31,8 +31,10 @@ import java.util.Set;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.entities.Machine;
import org.libreplan.web.calendars.BaseCalendarEditionController;
import org.libreplan.web.calendars.IBaseCalendarModel;
@ -40,13 +42,16 @@ import org.libreplan.web.common.BaseCRUDController;
import org.libreplan.web.common.ConstraintChecker;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.ILimitsModel;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.finders.FilterPair;
import org.libreplan.web.costcategories.ResourcesCostCategoryAssignmentController;
import org.libreplan.web.resources.search.ResourcePredicate;
import org.libreplan.web.resources.worker.CriterionsController;
import org.libreplan.web.resources.worker.CriterionsMachineController;
import org.libreplan.web.resources.worker.IWorkerModel;
import org.libreplan.web.resources.worker.WorkerCRUDController.LimitingResourceEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.CheckEvent;
@ -75,11 +80,19 @@ import org.zkoss.zul.api.Window;
* Controller for {@link Machine} resource <br />
* @author Diego Pino Garcia <dpino@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
public class MachineCRUDController extends BaseCRUDController<Machine> {
@Autowired
private ILimitsModel limitsModel;
@Autowired
private IMachineModel machineModel;
@Autowired
private IResourceDAO resourceDAO;
private Component configurationUnits;
private CriterionsMachineController criterionsController;
@ -149,9 +162,9 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
private void setupResourcesCostCategoryAssignmentController(Component comp) {
Component costCategoryAssignmentContainer =
editWindow.getFellowIfAny("costCategoryAssignmentContainer");
editWindow.getFellowIfAny("costCategoryAssignmentContainer");
resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController)
costCategoryAssignmentContainer.getVariable("assignmentController", true);
costCategoryAssignmentContainer.getVariable("assignmentController", true);
}
@Override
@ -447,11 +460,11 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
LocalDate finishDate = null;
if (filterStartDate.getValue() != null) {
startDate = LocalDate.fromDateFields(filterStartDate
.getValue());
.getValue());
}
if (filterFinishDate.getValue() != null) {
finishDate = LocalDate.fromDateFields(filterFinishDate
.getValue());
.getValue());
}
final Listitem item = filterLimitingResource.getSelectedItem();
@ -488,7 +501,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
private void setupFilterLimitingResourceListbox() {
for(LimitingResourceEnum resourceEnum :
LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
Listitem item = new Listitem();
item.setParent(filterLimitingResource);
item.setValue(resourceEnum);
@ -566,7 +579,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
row.addEventListener(Events.ON_CLICK,
new EventListener() {
@Override
public void onEvent(Event event) {
public void onEvent(Event event) {
goToEditForm(machine);
}
});
@ -611,4 +624,27 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
return machineModel.getMachine();
}
public boolean isCreateButtonDisabled(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return true;
return false;
}
public String getShowCreateFormLabel(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return _("Machines limit reached");
return _("Create") + " ( " + resourcesLeft + " " + _("left") + " )";
}
}

View file

@ -402,5 +402,4 @@ public class MachineModel extends IntegrationEntityModel implements
calendarToRemove = machine.getCalendar();
machine.setCalendar(null);
}
}

View file

@ -146,5 +146,4 @@ public interface IWorkerModel extends IIntegrationEntityModel {
void setBoundUser(User user);
User getBoundUserFromDB(Worker worker);
}

View file

@ -35,8 +35,10 @@ import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.entities.ResourceType;
import org.libreplan.business.resources.entities.VirtualWorker;
import org.libreplan.business.resources.entities.Worker;
@ -44,13 +46,14 @@ import org.libreplan.business.users.entities.User;
import org.libreplan.business.users.entities.UserRole;
import org.libreplan.web.calendars.BaseCalendarEditionController;
import org.libreplan.web.calendars.IBaseCalendarModel;
import org.libreplan.web.common.BaseCRUDController.CRUDControllerState;
import org.libreplan.web.common.ConstraintChecker;
import org.libreplan.web.common.IMessagesForUser;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.common.OnlyOneVisible;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.ILimitsModel;
import org.libreplan.web.common.BaseCRUDController.CRUDControllerState;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.libreplan.web.common.components.finders.FilterPair;
@ -98,6 +101,7 @@ import org.zkoss.zul.api.Window;
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
public class WorkerCRUDController extends GenericForwardComposer implements
IWorkerCRUDControllerEntryPoints {
@ -105,6 +109,15 @@ public class WorkerCRUDController extends GenericForwardComposer implements
@Autowired
private IDBPasswordEncoderService dbPasswordEncoderService;
@Autowired
private ILimitsModel limitsModel;
@Autowired
private IWorkerModel workerModel;
@Autowired
private IResourceDAO resourceDAO;
@Resource
private IUserCRUDController userCRUD;
@ -112,8 +125,6 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private Window editWindow;
private IWorkerModel workerModel;
private IURLHandlerRegistry URLHandlerRegistry;
private OnlyOneVisible visibility;
@ -200,10 +211,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements
}
public WorkerCRUDController(Window listWindow, Window editWindow,
Window editCalendarWindow,
IWorkerModel workerModel,
IMessagesForUser messages,
IWorkerCRUDControllerEntryPoints workerCRUD) {
Window editCalendarWindow,
IWorkerModel workerModel,
IMessagesForUser messages,
IWorkerCRUDControllerEntryPoints workerCRUD) {
this.listWindow = listWindow;
this.editWindow = editWindow;
this.workerModel = workerModel;
@ -504,7 +515,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
Radio radio = new Radio(_(option.label));
if (option.equals(UserBindingOption.CREATE_NEW_USER)
&& !SecurityUtils
.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) {
.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) {
radio.setDisabled(true);
radio.setTooltiptext(_("You do not have permissions to create new users"));
}
@ -524,7 +535,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
this.filterStartDate = (Datebox) listWindow
.getFellowIfAny("filterStartDate");
this.filterLimitingResource = (Listbox) listWindow
.getFellowIfAny("filterLimitingResource");
.getFellowIfAny("filterLimitingResource");
this.bdFilters = (BandboxMultipleSearch) listWindow
.getFellowIfAny("bdFilters");
this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter");
@ -534,9 +545,9 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private void setupResourcesCostCategoryAssignmentController(Component comp) {
Component costCategoryAssignmentContainer =
editWindow.getFellowIfAny("costCategoryAssignmentContainer");
editWindow.getFellowIfAny("costCategoryAssignmentContainer");
resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController)
costCategoryAssignmentContainer.getVariable("assignmentController", true);
costCategoryAssignmentContainer.getVariable("assignmentController", true);
}
private void editAsignedCriterions() {
@ -646,7 +657,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
}
private Window getCurrentWindow() {
return editWindow;
return editWindow;
}
private void updateCalendarController() {
@ -912,7 +923,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private void setupFilterLimitingResourceListbox() {
for(LimitingResourceEnum resourceEnum :
LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
Listitem item = new Listitem();
item.setParent(filterLimitingResource);
item.setValue(resourceEnum);
@ -1010,7 +1021,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
row.addEventListener(Events.ON_CLICK,
new EventListener() {
@Override
public void onEvent(Event event) {
public void onEvent(Event event) {
goToEditForm(worker);
}
});
@ -1054,19 +1065,19 @@ public class WorkerCRUDController extends GenericForwardComposer implements
String title;
switch (state) {
case CREATE:
if (StringUtils.isEmpty(humanId)) {
title = _("Create {0}", entityType);
} else {
title = _("Create {0}: {1}", entityType, humanId);
}
break;
case EDIT:
title = _("Edit {0}: {1}", entityType, humanId);
break;
default:
throw new IllegalStateException(
"You should be in creation or edition mode to use this method");
case CREATE:
if (StringUtils.isEmpty(humanId)) {
title = _("Create {0}", entityType);
} else {
title = _("Create {0}: {1}", entityType, humanId);
}
break;
case EDIT:
title = _("Edit {0}: {1}", entityType, humanId);
break;
default:
throw new IllegalStateException(
"You should be in creation or edition mode to use this method");
}
((Caption) editWindow.getFellow("caption")).setLabel(title);
}
@ -1159,4 +1170,27 @@ public class WorkerCRUDController extends GenericForwardComposer implements
return "";
}
public boolean isCreateButtonDisabled(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return true;
return false;
}
public String getShowCreateFormLabel(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return _("Workers limit reached");
return _("Create") + " ( " + resourcesLeft + " " + _("left") + " )";
}
}

View file

@ -49,6 +49,8 @@ import org.libreplan.business.planner.daos.IDayAssignmentDAO;
import org.libreplan.business.planner.daos.IResourceAllocationDAO;
import org.libreplan.business.resources.daos.ICriterionDAO;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.daos.IWorkerDAO;
import org.libreplan.business.resources.daos.WorkerDAO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionSatisfaction;
import org.libreplan.business.resources.entities.CriterionWithItsType;
@ -81,6 +83,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Diego Pino García <dpino@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -96,6 +99,9 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
@Autowired
private IBaseCalendarDAO baseCalendarDAO;
@Autowired
private IWorkerDAO workerDAO;
private final ICriterionType<?>[] laboralRelatedTypes = {
PredefinedCriterionTypes.LOCATION,
PredefinedCriterionTypes.CATEGORY, PredefinedCriterionTypes.SKILL };
@ -696,5 +702,4 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
}
return null;
}
}

View file

@ -34,6 +34,7 @@ import org.libreplan.business.users.entities.UserRole;
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
public interface IUserModel {
@ -134,4 +135,5 @@ public interface IUserModel {
List<Profile> getAllProfiles();
Number getRowCount();
}

View file

@ -32,6 +32,7 @@ import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.logging.LogFactory;
import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.resources.entities.Worker;
@ -40,12 +41,14 @@ import org.libreplan.business.users.entities.User;
import org.libreplan.business.users.entities.User.UserAuthenticationType;
import org.libreplan.business.users.entities.UserRole;
import org.libreplan.web.common.BaseCRUDController;
import org.libreplan.web.common.ILimitsModel;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.entrypoints.EntryPointsHandler;
import org.libreplan.web.common.entrypoints.IURLHandlerRegistry;
import org.libreplan.web.resources.worker.IWorkerCRUDControllerEntryPoints;
import org.libreplan.web.security.SecurityUtils;
import org.libreplan.web.users.bootstrap.PredefinedUsers;
import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
@ -61,12 +64,15 @@ import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.api.Groupbox;
import static org.libreplan.web.I18nHelper._;
/**
* Controller for CRUD actions over a {@link User}
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@SuppressWarnings("serial")
public class UserCRUDController extends BaseCRUDController<User> implements
@ -77,6 +83,10 @@ public class UserCRUDController extends BaseCRUDController<User> implements
@Resource
private IWorkerCRUDControllerEntryPoints workerCRUD;
@Autowired
private ILimitsModel limitsModel;
@Autowired
private IUserModel userModel;
private Textbox passwordBox;
@ -89,6 +99,8 @@ public class UserCRUDController extends BaseCRUDController<User> implements
private Combobox profilesCombo;
private Button showCreateForm;
private IURLHandlerRegistry URLHandlerRegistry;
private RowRenderer usersRenderer = new RowRenderer() {
@ -107,16 +119,16 @@ public class UserCRUDController extends BaseCRUDController<User> implements
Button[] buttons = Util.appendOperationsAndOnClickEvent(row,
new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
goToEditForm(user);
}
}, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
confirmDelete(user);
}
});
@Override
public void onEvent(Event event) throws Exception {
goToEditForm(user);
}
}, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
confirmDelete(user);
}
});
// Disable remove button for default admin as it's mandatory
if (isDefaultAdmin(user)) {
@ -248,7 +260,7 @@ public class UserCRUDController extends BaseCRUDController<User> implements
userModel.setPassword(password);
//update the constraint on the confirmation password box
((Textbox)editWindow.getFellowIfAny("passwordConfirmation")).
clearErrorMessage(true);
clearErrorMessage(true);
}
public Constraint validatePasswordConfirmation() {
@ -370,11 +382,11 @@ public class UserCRUDController extends BaseCRUDController<User> implements
Button removeButton = Util
.createRemoveButton(new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
removeRole(role);
}
});
@Override
public void onEvent(Event event) throws Exception {
removeRole(role);
}
});
removeButton.setDisabled(areRolesAndProfilesDisabled()
|| role.equals(UserRole.ROLE_BOUND_USER)
|| isUserDefaultAdmin());
@ -491,4 +503,23 @@ public class UserCRUDController extends BaseCRUDController<User> implements
}
}
public boolean isCreateButtonDisabled(){
Limits usersTypeLimit = limitsModel.getUsersType();
Integer usersCount = (Integer) userModel.getRowCount();
if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() )
return true;
return false;
}
public String getShowCreateFormLabel(){
Limits usersTypeLimit = limitsModel.getUsersType();
Integer usersCount = (Integer) userModel.getRowCount();
int usersLeft = usersTypeLimit.getValue() - usersCount;
if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() )
return _("User limit reached");
return _("Create") + " ( " + usersLeft + " " + _("left") + " )";
}
}

View file

@ -50,6 +50,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -275,4 +276,11 @@ public class UserModel implements IUserModel {
return profileDAO.listSorted();
}
@Override
@Transactional(readOnly = true)
public Number getRowCount() {
return userDAO.getRowCount();
}
}

View file

@ -8631,6 +8631,9 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/advance/_listAdvanceTypes.zul:33
#: libreplan-webapp/src/main/webapp/unittypes/_listUnitTypes.zul:32
#: libreplan-webapp/src/main/webapp/qualityforms/_listQualityForm.zul:58
#: libreplan-webapp/src/main/java/org/libreplan/web/users/UserCRUDController.java:523
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/machine/MachineCRUDController.java:640
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java:1187
msgid "Create"
msgstr ""
@ -9287,3 +9290,25 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/dashboard/_pipeline.zul:2
msgid "Show archived column data"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/users/UserCRUDController.java:520
msgid "User limit reached"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/users/UserCRUDController.java:523
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/machine/MachineCRUDController.java:640
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java:1187
msgid "left"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerCRUDController.java:1178
msgid "Workers limit reached"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/machine/MachineCRUDController.java:631
msgid "Machines limit reached"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java:247
msgid "Check fields"
msgstr ""

View file

@ -40,6 +40,7 @@
</columns>
</newdatasortablegrid>
<button id="show_create_form" onClick="controller.goToCreateForm();"
label="${i18n:_('Create')}" sclass="create-button global-action">
label="@{controller.getShowCreateFormLabel}" sclass="create-button global-action"
disabled="@{controller.isCreateButtonDisabled}">
</button>
</window>

View file

@ -42,6 +42,7 @@
</newdatasortablegrid>
<button id="show_create_form" onClick="controller.goToCreateForm();"
label="${i18n:_('Create')}" sclass="create-button global-action">
label="@{controller.getShowCreateFormLabel}" sclass="create-button global-action"
disabled="@{controller.isCreateButtonDisabled}">
</button>
</window>

View file

@ -35,6 +35,7 @@
</columns>
</newdatasortablegrid>
<button id="show_create_form" onClick="controller.goToCreateForm();"
label="${i18n:_('Create')}" sclass="create-button global-action" >
label="@{controller.getShowCreateFormLabel}" sclass="create-button global-action"
disabled="@{controller.isCreateButtonDisabled}">
</button>
</window>

View file

@ -45,6 +45,9 @@ import javax.annotation.Resource;
import javax.xml.datatype.XMLGregorianCalendar;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.junit.Test;
@ -92,6 +95,7 @@ import org.springframework.transaction.annotation.Transactional;
* Tests for {@link IWorkReportService}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
@ -576,11 +580,25 @@ public class WorkReportServiceTest {
instanceConstraintViolationsListDTO.instanceConstraintViolationsList
.size(), equalTo(0));
List<WorkReport> workReports = workReportDAO.getAll();
/**
* Default code that was before was not working with MySQL
* and works perfect with PostgreSQL
* For example: List<WorkReport> workReports = workReportDAO.getAll();
* was returning 0 but COUNT in DB was 1
* Also set workReportLines in WorkReports.hbm.xml has been changed to fetch='join'
* Possible reason: Hibernate 4.3.11.Final bug / caching
*/
StatelessSession statelessSession = sessionFactory.openStatelessSession();
List<WorkReport> workReports = statelessSession.createCriteria(WorkReport.class)
.addOrder(Order.asc("code")).list();
assertThat(workReports.size(), equalTo(previous + 1));
WorkReport imported = workReportDAO
.findExistingEntityByCode(workReportDTO.code);
WorkReport imported = (WorkReport) statelessSession.createCriteria(WorkReport.class)
.add(Restrictions.eq("code", workReportDTO.code.trim()).ignoreCase()).uniqueResult();
assertThat(imported.getDate(), equalTo(date));
List<WorkReportLine> importedLines = new ArrayList<WorkReportLine>(
@ -600,6 +618,7 @@ public class WorkReportServiceTest {
WorkReportLine line = importedLines.remove(0);
assertThat(line.getDate().getTime(), equalTo(asTime(each.getDate())));
}
statelessSession.close();
}
private long asTime(XMLGregorianCalendar date2) {