Add Limits functionality.
Changes to INSTALL and HACKING documents.

(cherry picked from commit 0a0af1e9cded313ac4d5293d16cf834346287ccb)
This commit is contained in:
Vova Perebykivskiy 2015-12-22 17:51:39 +02:00 committed by Dgray16
parent 58b8a3e1c5
commit c0b9dcdec5
22 changed files with 153 additions and 166 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) # 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) # 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/ # http://sourceforge.net/projects/libreplan/files/LibrePlan/
* Create database:: * Create database::
@ -266,15 +264,12 @@ Microsoft Windows
GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan; GRANT ALL PRIVILEGES ON DATABASE libreplan TO libreplan;
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup::
* Create an Environment Variable JAVA_HOME * Create an Environment Variable JAVA_HOME
# You need to set it to your JDK installed directory # You need to set it to your JDK installed directory
* Configure Apache Tomcat Server * 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: # 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"?> <?xml version="1.0" encoding="UTF-8"?>
@ -288,13 +283,7 @@ Microsoft Windows
url="jdbc:postgresql://localhost/libreplan" /> url="jdbc:postgresql://localhost/libreplan" />
</Context> </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:: * Download source code::
@ -316,8 +305,12 @@ Microsoft Windows
* Launch application:: * Launch application::
# cd libreplan-webapp * Get *.war file from project folder (e.g ../libreplan/libreplan-webapp/target/libreplan-webapp.war)
# mvn jetty:run * 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/ * Go to http://localhost:8080/libreplan-webapp/

View file

@ -326,7 +326,7 @@ Microsoft Windows
Instructions: 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 # http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html
@ -367,7 +367,7 @@ Instructions:
ON ALL TABLES IN SCHEMA public ON ALL TABLES IN SCHEMA public
TO libreplan; TO libreplan;
* Restore PostgreSQL dump - scripts/database/postgresql_1.4.1.backup:: * Restore PostgreSQL / MySQL dump::
* Create an Environment Variable JRE_HOME * Create an Environment Variable JRE_HOME

View file

@ -35,6 +35,5 @@ public interface ILimitsDAO extends IGenericDAO<Limits, Long> {
List<Limits> getAll(); List<Limits> getAll();
Limits getUsersType(); Limits getUsersType();
Limits getWorkersType(); Limits getResourcesType();
Limits getMachinesType();
} }

View file

@ -49,19 +49,10 @@ public class LimitsDAO extends GenericDAOHibernate<Limits, Long> implements ILim
} }
@Override @Override
public Limits getWorkersType() { public Limits getResourcesType() {
List<Limits> list = list(Limits.class); List<Limits> list = list(Limits.class);
for (Limits item : list) for (Limits item : list)
if (item.getType().equals("workers")) return item; if (item.getType().equals("workers+machines")) return item;
return null; return null;
} }
@Override
public Limits getMachinesType() {
List<Limits> list = list(Limits.class);
for (Limits item : list)
if (item.getType().equals("machines")) return item;
return null;
}
} }

View file

@ -34,7 +34,7 @@ public class Limits extends BaseEntity{
private String type; private String type;
private Long value; private Integer value;
public String getType() { public String getType() {
@ -44,10 +44,10 @@ public class Limits extends BaseEntity{
this.type = type; this.type = type;
} }
public Long getValue() { public Integer getValue() {
return value; return value;
} }
public void setValue(Long value) { public void setValue(Integer value) {
this.value = value; this.value = value;
} }
} }

View file

@ -33,7 +33,6 @@ import org.libreplan.business.resources.entities.Machine;
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
public interface IMachineDAO extends IIntegrationEntityDAO<Machine> { public interface IMachineDAO extends IIntegrationEntityDAO<Machine> {
@ -83,9 +82,4 @@ public interface IMachineDAO extends IIntegrationEntityDAO<Machine> {
* code as the one passed as parameter * code as the one passed as parameter
*/ */
boolean existsMachineWithCodeInAnotherTransaction(String code); boolean existsMachineWithCodeInAnotherTransaction(String code);
/**
* Return a number of rows in database table
*/
Number getRowCount();
} }

View file

@ -120,4 +120,6 @@ public interface IResourceDAO extends IIntegrationEntityDAO<Resource> {
*/ */
List<HoursWorkedPerWorkerInAMonthDTO> getWorkingHoursPerWorker(Integer year, Integer month); 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 Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> { public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> {
@ -127,6 +126,4 @@ public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> {
* Return the list of {@link Worker Workers} bound to any {@link User}. * Return the list of {@link Worker Workers} bound to any {@link User}.
*/ */
List<Worker> getBound(); List<Worker> getBound();
Number getRowCount();
} }

View file

@ -41,7 +41,6 @@ import org.springframework.transaction.annotation.Transactional;
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
@ -84,11 +83,6 @@ public class MachineDAO extends IntegrationEntityDAO<Machine>
} }
} }
@Override
public Number getRowCount() {
return (Number) getSession().createCriteria(Machine.class).setProjection(Projections.rowCount()).uniqueResult();
}
@Override @Override
@Transactional(readOnly= true, propagation = Propagation.REQUIRES_NEW) @Transactional(readOnly= true, propagation = Propagation.REQUIRES_NEW)
public Machine findUniqueByCodeInAnotherTransaction(String code) public Machine findUniqueByCodeInAnotherTransaction(String code)

View file

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

View file

@ -44,7 +44,6 @@ import org.springframework.transaction.annotation.Transactional;
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
@ -199,10 +198,4 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
criteria.add(Restrictions.isNotNull("user")); criteria.add(Restrictions.isNotNull("user"));
return criteria.list(); return criteria.list();
} }
@Override
public Number getRowCount() {
return (Number) getSession().createCriteria(Worker.class).setProjection(Projections.rowCount()).uniqueResult();
}
} }

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<changeSet id="add-id_cost_category-column-to-criterion-table" author="ltilve"> <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"> <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> <comment>Add foreign key constraint to new id_cost_category column on cost_category id</comment>
<addForeignKeyConstraint constraintName="cost_category_fkey" <addForeignKeyConstraint constraintName="cost_category_fkey"
baseTableName="criterion" baseColumnNames="id_cost_category" baseTableName="criterion" baseColumnNames="id_cost_category"
referencedTableName="cost_category" referencedColumnNames="id" referencedTableName="cost_category" referencedColumnNames="id"
onDelete="SET NULL" /> onDelete="SET NULL" />
</changeSet> </changeSet>
<changeSet id="add-new-column-automatic_budget_enabled" author="ltilve"> <changeSet id="add-new-column-automatic_budget_enabled" author="ltilve">
@ -25,11 +25,11 @@
<column name="automatic_budget_enabled" type="BOOLEAN" /> <column name="automatic_budget_enabled" type="BOOLEAN" />
</addColumn> </addColumn>
<addDefaultValue tableName="configuration" columnName="automatic_budget_enabled" <addDefaultValue tableName="configuration" columnName="automatic_budget_enabled"
defaultValueBoolean="FALSE" /> defaultValueBoolean="FALSE" />
<addNotNullConstraint tableName="configuration" <addNotNullConstraint tableName="configuration"
columnName="automatic_budget_enabled" columnName="automatic_budget_enabled"
defaultNullValue="FALSE" defaultNullValue="FALSE"
columnDataType="BOOLEAN" /> columnDataType="BOOLEAN" />
</changeSet> </changeSet>
<changeSet id="add-automatic_budget_type_of_work_hours-to-configuration" author="ltilve"> <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" /> <column name="automatic_budget_type_of_work_hours" type="BIGINT" />
</addColumn> </addColumn>
<addForeignKeyConstraint constraintName="automatic_budget_type_of_work_hours_fkey" <addForeignKeyConstraint constraintName="automatic_budget_type_of_work_hours_fkey"
baseTableName="configuration" baseColumnNames="automatic_budget_type_of_work_hours" baseTableName="configuration" baseColumnNames="automatic_budget_type_of_work_hours"
referencedTableName="type_of_work_hours" referencedColumnNames="id" /> 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> </changeSet>
</databaseChangeLog> </databaseChangeLog>

View file

@ -34,6 +34,5 @@ public interface ILimitsModel {
List<Limits> getAll(); List<Limits> getAll();
Limits getUsersType(); Limits getUsersType();
Limits getWorkersType(); Limits getResourcesType();
Limits getMachinesType();
} }

View file

@ -58,13 +58,7 @@ public class LimitsModel implements ILimitsModel {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public Limits getWorkersType() { public Limits getResourcesType() {
return limitsDAO.getWorkersType(); return limitsDAO.getResourcesType();
}
@Override
@Transactional(readOnly = true)
public Limits getMachinesType() {
return limitsDAO.getMachinesType();
} }
} }

View file

@ -63,7 +63,6 @@ import org.libreplan.web.resources.search.ResourcePredicate;
* *
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
public interface IMachineModel extends IIntegrationEntityModel { public interface IMachineModel extends IIntegrationEntityModel {
// Initial conversational steps // Initial conversational steps
@ -108,7 +107,4 @@ public interface IMachineModel extends IIntegrationEntityModel {
void confirmRemove(Machine machine) throws InstanceNotFoundException; void confirmRemove(Machine machine) throws InstanceNotFoundException;
void removeCalendar(); void removeCalendar();
Number getRowCount();
} }

View file

@ -34,6 +34,7 @@ import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.entities.Limits; import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.common.exceptions.ValidationException;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.entities.Machine; import org.libreplan.business.resources.entities.Machine;
import org.libreplan.web.calendars.BaseCalendarEditionController; import org.libreplan.web.calendars.BaseCalendarEditionController;
import org.libreplan.web.calendars.IBaseCalendarModel; import org.libreplan.web.calendars.IBaseCalendarModel;
@ -48,6 +49,7 @@ import org.libreplan.web.costcategories.ResourcesCostCategoryAssignmentControlle
import org.libreplan.web.resources.search.ResourcePredicate; import org.libreplan.web.resources.search.ResourcePredicate;
import org.libreplan.web.resources.worker.CriterionsController; import org.libreplan.web.resources.worker.CriterionsController;
import org.libreplan.web.resources.worker.CriterionsMachineController; import org.libreplan.web.resources.worker.CriterionsMachineController;
import org.libreplan.web.resources.worker.IWorkerModel;
import org.libreplan.web.resources.worker.WorkerCRUDController.LimitingResourceEnum; import org.libreplan.web.resources.worker.WorkerCRUDController.LimitingResourceEnum;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
@ -88,6 +90,9 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
@Autowired @Autowired
private IMachineModel machineModel; private IMachineModel machineModel;
@Autowired
private IResourceDAO resourceDAO;
private Component configurationUnits; private Component configurationUnits;
private CriterionsMachineController criterionsController; private CriterionsMachineController criterionsController;
@ -157,9 +162,9 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
private void setupResourcesCostCategoryAssignmentController(Component comp) { private void setupResourcesCostCategoryAssignmentController(Component comp) {
Component costCategoryAssignmentContainer = Component costCategoryAssignmentContainer =
editWindow.getFellowIfAny("costCategoryAssignmentContainer"); editWindow.getFellowIfAny("costCategoryAssignmentContainer");
resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController) resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController)
costCategoryAssignmentContainer.getVariable("assignmentController", true); costCategoryAssignmentContainer.getVariable("assignmentController", true);
} }
@Override @Override
@ -455,11 +460,11 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
LocalDate finishDate = null; LocalDate finishDate = null;
if (filterStartDate.getValue() != null) { if (filterStartDate.getValue() != null) {
startDate = LocalDate.fromDateFields(filterStartDate startDate = LocalDate.fromDateFields(filterStartDate
.getValue()); .getValue());
} }
if (filterFinishDate.getValue() != null) { if (filterFinishDate.getValue() != null) {
finishDate = LocalDate.fromDateFields(filterFinishDate finishDate = LocalDate.fromDateFields(filterFinishDate
.getValue()); .getValue());
} }
final Listitem item = filterLimitingResource.getSelectedItem(); final Listitem item = filterLimitingResource.getSelectedItem();
@ -496,7 +501,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
private void setupFilterLimitingResourceListbox() { private void setupFilterLimitingResourceListbox() {
for(LimitingResourceEnum resourceEnum : for(LimitingResourceEnum resourceEnum :
LimitingResourceEnum.getLimitingResourceFilterOptionList()) { LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
Listitem item = new Listitem(); Listitem item = new Listitem();
item.setParent(filterLimitingResource); item.setParent(filterLimitingResource);
item.setValue(resourceEnum); item.setValue(resourceEnum);
@ -574,7 +579,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
row.addEventListener(Events.ON_CLICK, row.addEventListener(Events.ON_CLICK,
new EventListener() { new EventListener() {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
goToEditForm(machine); goToEditForm(machine);
} }
}); });
@ -620,23 +625,26 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
} }
public boolean isCreateButtonDisabled(){ public boolean isCreateButtonDisabled(){
Limits machinesTypeLimit = limitsModel.getMachinesType(); Limits resourcesTypeLimit = limitsModel.getResourcesType();
Long machinesCount = (Long) machineModel.getRowCount(); Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( machinesTypeLimit != null )
if ( machinesCount >= machinesTypeLimit.getValue() ) if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return true; return true;
return false; return false;
} }
public String getShowCreateFormLabel(){ public String getShowCreateFormLabel(){
Limits machinesTypeLimit = limitsModel.getMachinesType(); Limits resourcesTypeLimit = limitsModel.getResourcesType();
Long machinesCount = (Long) machineModel.getRowCount(); Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( machinesTypeLimit != null )
if ( machinesCount >= machinesTypeLimit.getValue() ) int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return _("Machines limit reached"); return _("Machines limit reached");
return _("Create"); return _("Create") + " ( " + resourcesLeft + " " + _("left") + " )";
} }
} }

View file

@ -70,7 +70,6 @@ import org.springframework.transaction.annotation.Transactional;
/** /**
* @author Diego Pino Garcia <dpino@igalia.com> * @author Diego Pino Garcia <dpino@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com> * @author Javier Moran Rua <jmoran@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
@Service @Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -403,12 +402,4 @@ public class MachineModel extends IntegrationEntityModel implements
calendarToRemove = machine.getCalendar(); calendarToRemove = machine.getCalendar();
machine.setCalendar(null); machine.setCalendar(null);
} }
@Override
@Transactional(readOnly = true)
public Number getRowCount() {
return machineDAO.getRowCount();
}
} }

View file

@ -74,7 +74,6 @@ import org.libreplan.web.resources.search.ResourcePredicate;
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es> * @author Fernando Bellas Permuy <fbellas@udc.es>
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
public interface IWorkerModel extends IIntegrationEntityModel { public interface IWorkerModel extends IIntegrationEntityModel {
@ -147,7 +146,4 @@ public interface IWorkerModel extends IIntegrationEntityModel {
void setBoundUser(User user); void setBoundUser(User user);
User getBoundUserFromDB(Worker worker); User getBoundUserFromDB(Worker worker);
Number getRowCount();
} }

View file

@ -38,6 +38,7 @@ import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.entities.Limits; import org.libreplan.business.common.entities.Limits;
import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.common.exceptions.ValidationException; 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.ResourceType;
import org.libreplan.business.resources.entities.VirtualWorker; import org.libreplan.business.resources.entities.VirtualWorker;
import org.libreplan.business.resources.entities.Worker; import org.libreplan.business.resources.entities.Worker;
@ -114,6 +115,9 @@ public class WorkerCRUDController extends GenericForwardComposer implements
@Autowired @Autowired
private IWorkerModel workerModel; private IWorkerModel workerModel;
@Autowired
private IResourceDAO resourceDAO;
@Resource @Resource
private IUserCRUDController userCRUD; private IUserCRUDController userCRUD;
@ -207,10 +211,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements
} }
public WorkerCRUDController(Window listWindow, Window editWindow, public WorkerCRUDController(Window listWindow, Window editWindow,
Window editCalendarWindow, Window editCalendarWindow,
IWorkerModel workerModel, IWorkerModel workerModel,
IMessagesForUser messages, IMessagesForUser messages,
IWorkerCRUDControllerEntryPoints workerCRUD) { IWorkerCRUDControllerEntryPoints workerCRUD) {
this.listWindow = listWindow; this.listWindow = listWindow;
this.editWindow = editWindow; this.editWindow = editWindow;
this.workerModel = workerModel; this.workerModel = workerModel;
@ -511,7 +515,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
Radio radio = new Radio(_(option.label)); Radio radio = new Radio(_(option.label));
if (option.equals(UserBindingOption.CREATE_NEW_USER) if (option.equals(UserBindingOption.CREATE_NEW_USER)
&& !SecurityUtils && !SecurityUtils
.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) { .isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) {
radio.setDisabled(true); radio.setDisabled(true);
radio.setTooltiptext(_("You do not have permissions to create new users")); radio.setTooltiptext(_("You do not have permissions to create new users"));
} }
@ -531,7 +535,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
this.filterStartDate = (Datebox) listWindow this.filterStartDate = (Datebox) listWindow
.getFellowIfAny("filterStartDate"); .getFellowIfAny("filterStartDate");
this.filterLimitingResource = (Listbox) listWindow this.filterLimitingResource = (Listbox) listWindow
.getFellowIfAny("filterLimitingResource"); .getFellowIfAny("filterLimitingResource");
this.bdFilters = (BandboxMultipleSearch) listWindow this.bdFilters = (BandboxMultipleSearch) listWindow
.getFellowIfAny("bdFilters"); .getFellowIfAny("bdFilters");
this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter"); this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter");
@ -541,9 +545,9 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private void setupResourcesCostCategoryAssignmentController(Component comp) { private void setupResourcesCostCategoryAssignmentController(Component comp) {
Component costCategoryAssignmentContainer = Component costCategoryAssignmentContainer =
editWindow.getFellowIfAny("costCategoryAssignmentContainer"); editWindow.getFellowIfAny("costCategoryAssignmentContainer");
resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController) resourcesCostCategoryAssignmentController = (ResourcesCostCategoryAssignmentController)
costCategoryAssignmentContainer.getVariable("assignmentController", true); costCategoryAssignmentContainer.getVariable("assignmentController", true);
} }
private void editAsignedCriterions() { private void editAsignedCriterions() {
@ -653,7 +657,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
} }
private Window getCurrentWindow() { private Window getCurrentWindow() {
return editWindow; return editWindow;
} }
private void updateCalendarController() { private void updateCalendarController() {
@ -919,7 +923,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private void setupFilterLimitingResourceListbox() { private void setupFilterLimitingResourceListbox() {
for(LimitingResourceEnum resourceEnum : for(LimitingResourceEnum resourceEnum :
LimitingResourceEnum.getLimitingResourceFilterOptionList()) { LimitingResourceEnum.getLimitingResourceFilterOptionList()) {
Listitem item = new Listitem(); Listitem item = new Listitem();
item.setParent(filterLimitingResource); item.setParent(filterLimitingResource);
item.setValue(resourceEnum); item.setValue(resourceEnum);
@ -1017,7 +1021,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
row.addEventListener(Events.ON_CLICK, row.addEventListener(Events.ON_CLICK,
new EventListener() { new EventListener() {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
goToEditForm(worker); goToEditForm(worker);
} }
}); });
@ -1061,19 +1065,19 @@ public class WorkerCRUDController extends GenericForwardComposer implements
String title; String title;
switch (state) { switch (state) {
case CREATE: case CREATE:
if (StringUtils.isEmpty(humanId)) { if (StringUtils.isEmpty(humanId)) {
title = _("Create {0}", entityType); title = _("Create {0}", entityType);
} else { } else {
title = _("Create {0}: {1}", entityType, humanId); title = _("Create {0}: {1}", entityType, humanId);
} }
break; break;
case EDIT: case EDIT:
title = _("Edit {0}: {1}", entityType, humanId); title = _("Edit {0}: {1}", entityType, humanId);
break; break;
default: default:
throw new IllegalStateException( throw new IllegalStateException(
"You should be in creation or edition mode to use this method"); "You should be in creation or edition mode to use this method");
} }
((Caption) editWindow.getFellow("caption")).setLabel(title); ((Caption) editWindow.getFellow("caption")).setLabel(title);
} }
@ -1167,23 +1171,26 @@ public class WorkerCRUDController extends GenericForwardComposer implements
} }
public boolean isCreateButtonDisabled(){ public boolean isCreateButtonDisabled(){
Limits workersTypeLimit = limitsModel.getWorkersType(); Limits resourcesTypeLimit = limitsModel.getResourcesType();
Long workersCount = (Long) workerModel.getRowCount(); Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( workersTypeLimit != null )
if ( workersCount >= workersTypeLimit.getValue() ) if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return true; return true;
return false; return false;
} }
public String getShowCreateFormLabel(){ public String getShowCreateFormLabel(){
Limits workersTypeLimit = limitsModel.getWorkersType(); Limits resourcesTypeLimit = limitsModel.getResourcesType();
Long workersCount = (Long) workerModel.getRowCount(); Integer resourcesCount = (Integer) resourceDAO.getRowCount();
if ( workersTypeLimit != null )
if ( workersCount >= workersTypeLimit.getValue() ) int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
return _("Workers limit reached"); return _("Workers limit reached");
return _("Create"); return _("Create") + " ( " + resourcesLeft + " " + _("left") + " )";
} }
} }

View file

@ -702,11 +702,4 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
} }
return null; return null;
} }
@Override
@Transactional(readOnly = true)
public Number getRowCount() {
return workerDAO.getRowCount();
}
} }

View file

@ -119,16 +119,16 @@ public class UserCRUDController extends BaseCRUDController<User> implements
Button[] buttons = Util.appendOperationsAndOnClickEvent(row, Button[] buttons = Util.appendOperationsAndOnClickEvent(row,
new EventListener() { new EventListener() {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
goToEditForm(user); goToEditForm(user);
} }
}, new EventListener() { }, new EventListener() {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
confirmDelete(user); confirmDelete(user);
} }
}); });
// Disable remove button for default admin as it's mandatory // Disable remove button for default admin as it's mandatory
if (isDefaultAdmin(user)) { if (isDefaultAdmin(user)) {
@ -260,7 +260,7 @@ public class UserCRUDController extends BaseCRUDController<User> implements
userModel.setPassword(password); userModel.setPassword(password);
//update the constraint on the confirmation password box //update the constraint on the confirmation password box
((Textbox)editWindow.getFellowIfAny("passwordConfirmation")). ((Textbox)editWindow.getFellowIfAny("passwordConfirmation")).
clearErrorMessage(true); clearErrorMessage(true);
} }
public Constraint validatePasswordConfirmation() { public Constraint validatePasswordConfirmation() {
@ -382,11 +382,11 @@ public class UserCRUDController extends BaseCRUDController<User> implements
Button removeButton = Util Button removeButton = Util
.createRemoveButton(new EventListener() { .createRemoveButton(new EventListener() {
@Override @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
removeRole(role); removeRole(role);
} }
}); });
removeButton.setDisabled(areRolesAndProfilesDisabled() removeButton.setDisabled(areRolesAndProfilesDisabled()
|| role.equals(UserRole.ROLE_BOUND_USER) || role.equals(UserRole.ROLE_BOUND_USER)
|| isUserDefaultAdmin()); || isUserDefaultAdmin());
@ -505,7 +505,7 @@ public class UserCRUDController extends BaseCRUDController<User> implements
public boolean isCreateButtonDisabled(){ public boolean isCreateButtonDisabled(){
Limits usersTypeLimit = limitsModel.getUsersType(); Limits usersTypeLimit = limitsModel.getUsersType();
Long usersCount = (Long) userModel.getRowCount(); Integer usersCount = (Integer) userModel.getRowCount();
if (usersTypeLimit != null) if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() ) if ( usersCount >= usersTypeLimit.getValue() )
return true; return true;
@ -514,11 +514,12 @@ public class UserCRUDController extends BaseCRUDController<User> implements
public String getShowCreateFormLabel(){ public String getShowCreateFormLabel(){
Limits usersTypeLimit = limitsModel.getUsersType(); Limits usersTypeLimit = limitsModel.getUsersType();
Long usersCount = (Long) userModel.getRowCount(); Integer usersCount = (Integer) userModel.getRowCount();
int usersLeft = usersTypeLimit.getValue() - usersCount;
if (usersTypeLimit != null) if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() ) if ( usersCount >= usersTypeLimit.getValue() )
return _("User limit reached"); return _("User limit reached");
return _("Create"); return _("Create") + " ( " + usersLeft + " " + _("left") + " )";
} }
} }

View file

@ -8631,6 +8631,9 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/advance/_listAdvanceTypes.zul:33 #: libreplan-webapp/src/main/webapp/advance/_listAdvanceTypes.zul:33
#: libreplan-webapp/src/main/webapp/unittypes/_listUnitTypes.zul:32 #: libreplan-webapp/src/main/webapp/unittypes/_listUnitTypes.zul:32
#: libreplan-webapp/src/main/webapp/qualityforms/_listQualityForm.zul:58 #: 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" msgid "Create"
msgstr "" msgstr ""
@ -9292,7 +9295,13 @@ msgstr ""
msgid "User limit reached" msgid "User limit reached"
msgstr "" msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/UserCRUDController.java:1178 #: 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" msgid "Workers limit reached"
msgstr "" msgstr ""