Documents uploading/downloading feature + tests.

i18n.
Resolving bugs/issues.
Code refactoring.
Add Liquibase tip.
This commit is contained in:
Vova Perebykivskiy 2016-02-18 15:53:05 +02:00 committed by Tester
parent a2a936b313
commit d780b187bf
38 changed files with 1435 additions and 190 deletions

View file

@ -326,7 +326,7 @@ Microsoft Windows
Instructions:
* Download and install latest Java Runtime Environment 7u80 (JRE7u79)::
* Download and install latest Java Runtime Environment 7u80 (JRE7u80)::
# http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html

View file

@ -67,6 +67,7 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- datasource for testing -->
<dependency>
<groupId>com.jolbox</groupId>
@ -105,6 +106,7 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- Joda Time -->
<dependency>
<groupId>joda-time</groupId>
@ -127,6 +129,7 @@
<profiles>
<profile>
<!-- LiquiBase liquibase:update -->
<id>liquibase-update</id>
<activation>
@ -155,6 +158,7 @@
</build>
</profile>
<profile>
<!-- LiquiBase liquibase:updateSQL -->
<id>liquibase-updatesql</id>
<activation>

View file

@ -135,6 +135,8 @@ public class Configuration extends BaseEntity {
*/
private Integer maxResources = 0;
private String repositoryLocation;
public void setDefaultCalendar(BaseCalendar defaultCalendar) {
this.defaultCalendar = defaultCalendar;
@ -533,4 +535,11 @@ public class Configuration extends BaseEntity {
this.enabledAutomaticBudget = enabledAutomaticBudget;
}
public String getRepositoryLocation() {
return repositoryLocation;
}
public void setRepositoryLocation(String repositoryLocation) {
this.repositoryLocation = repositoryLocation;
}
}

View file

@ -19,8 +19,10 @@
package org.libreplan.business.email.daos;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.email.entities.EmailNotification;
import org.libreplan.business.email.entities.EmailTemplateEnum;
import org.springframework.stereotype.Repository;
import java.util.List;
@ -40,6 +42,12 @@ public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification,
return list(EmailNotification.class);
}
@Override
public List<EmailNotification> getAllByType(EmailTemplateEnum enumeration) {
return getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration)).list();
}
@Override
public boolean deleteAll() {
List<EmailNotification> notifications = list(EmailNotification.class);
@ -47,8 +55,28 @@ public class EmailNotificationDAO extends GenericDAOHibernate<EmailNotification,
getSession().delete(item);
}
if ( list(EmailNotification.class).size() == 0 ) return true;
return list(EmailNotification.class).size() == 0;
}
@Override
public boolean deleteAllByType(EmailTemplateEnum enumeration) {
List<EmailNotification> notifications = getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration)).list();
for (Object item : notifications){
getSession().delete(item);
}
if ( getSession().createCriteria(EmailNotification.class)
.add(Restrictions.eq("type", enumeration.ordinal())).list().size() == 0 ) return true;
return false;
}
@Override
public boolean deleteById(EmailNotification notification) {
getSession().delete(notification);
if ( getSession().createCriteria(EmailNotification.class).add(Restrictions.eq("id", notification.getId()))
.uniqueResult() != null ) return false;
return true;
}
}

View file

@ -21,6 +21,7 @@ package org.libreplan.business.email.daos;
import org.libreplan.business.common.daos.IGenericDAO;
import org.libreplan.business.email.entities.EmailNotification;
import org.libreplan.business.email.entities.EmailTemplateEnum;
import java.util.List;
@ -33,5 +34,9 @@ import java.util.List;
*/
public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Long> {
List<EmailNotification> getAll();
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
boolean deleteAll();
boolean deleteAllByType(EmailTemplateEnum enumeration);
boolean deleteById(EmailNotification notification);
}

View file

@ -0,0 +1,41 @@
/*
* 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.orders.daos;
import org.libreplan.business.common.daos.IGenericDAO;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import java.util.List;
/**
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/
public interface IOrderFileDAO extends IGenericDAO<OrderFile, Long> {
List<OrderFile> getAll();
void delete(OrderFile file);
List<OrderFile> findByParent(OrderElement parent);
}

View file

@ -0,0 +1,57 @@
/*
* 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.orders.daos;
import org.hibernate.criterion.Restrictions;
import org.libreplan.business.common.daos.GenericDAOHibernate;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/
@Repository
public class OrderFileDAO extends GenericDAOHibernate<OrderFile, Long> implements IOrderFileDAO {
@Override
public List<OrderFile> getAll() {
return list(OrderFile.class);
}
@Override
public void delete(OrderFile file) {
try {
remove(file.getId());
} catch (InstanceNotFoundException e) {}
}
@Override
public List<OrderFile> findByParent(OrderElement parent) {
return getSession().createCriteria(OrderFile.class)
.add(Restrictions.eq("parent", parent)).list();
}
}

View file

@ -0,0 +1,83 @@
/*
* 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.orders.entities;
import org.libreplan.business.common.BaseEntity;
import org.libreplan.business.users.entities.User;
import java.util.Date;
/**
* OrderFile entity representing table: files.
* This class is intended to work as a Hibernate component.
* It represents the LibrePlan File to be stored in customer`s HDD.
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 25.12.2015.
*/
public class OrderFile extends BaseEntity {
private String name;
private String type;
private Date date;
private User uploader;
private OrderElement parent;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUploader() {
return uploader;
}
public void setUploader(User uploader) {
this.uploader = uploader;
}
public OrderElement getParent() {
return parent;
}
public void setParent(OrderElement parent) {
this.parent = parent;
}
}

View file

@ -89,8 +89,14 @@ public enum UserRole {
ROLE_PROJECT_STATUS_REPORT(_("Project Status Report")),
ROLE_EDIT_EMAIL_TEMPLATES(_("Edit E-mail Templates")),
ROLE_USE_FILES(_("Use files for order")),
ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE(_("Email task assigned to resource"));
ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE(_("Email: task assigned to resource")),
ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK(_("Email: resource removed from task")),
ROLE_EMAIL_MILESTONE_REACHED(_("Email: milestone reached")),
ROLE_EMAIL_TASK_SHOULD_FINISH(_("Email: task should finish")),
ROLE_EMAIL_TASK_SHOULD_START(_("Email: task should start")),
ROLE_EMAIL_TIMESHEET_DATA_MISSING(_("Email: timesheet data missing"));
private final String displayName;

View file

@ -57,7 +57,7 @@
</createTable>
<addUniqueConstraint
constraintName="type"
constraintName="limits_type_uc"
columnNames="type"
deferrable="false"
disabled="false"

View file

@ -5,7 +5,7 @@
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<changeSet id="adding-email_template_table" author="vova/jeroen">
<changeSet id="adding-email_template-table" author="vova/jeroen">
<createTable tableName="email_template">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" primaryKeyName="email_templates_pkey"/>
@ -30,6 +30,14 @@
<createIndex tableName="email_template" indexName="type_index">
<column name="type"></column>
</createIndex>
<sql>
INSERT INTO email_template VALUES(1, 0, 3, 'Task assigned to resource : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(2, 1, 3, 'Resource removed from task : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(3, 2, 3, 'Milestone reached : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(4, 3, 3, 'Task should start : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(5, 4, 3, 'Task should finish : Autogenerated content text', 'Autogenerated subject text');
INSERT INTO email_template VALUES(6, 5, 3, 'Enter data to timesheet : Autogenerated content text', 'Autogenerated subject text');
</sql>
</changeSet>
<changeSet id="adding-notification_notification_queue" author="vova">
@ -45,13 +53,13 @@
</createTable>
<addUniqueConstraint
tableName="notification_queue"
columnNames="resource, task, project"
columnNames="type, resource, task, project"
deferrable="false"
disabled="false"
initiallyDeferred="false"/>
</changeSet>
<changeSet id="adding-issue_log_table" author="misha/vova">
<changeSet id="adding-issue_log-table" author="misha/vova">
<createTable tableName="issue_log">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" primaryKeyName="issue_log_pkey"/>
@ -89,7 +97,7 @@
/>
</changeSet>
<changeSet id="adding-risk_log_table" author="misha/vova">
<changeSet id="adding-risk_log-table" author="misha/vova">
<createTable tableName="risk_log">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" primaryKeyName="risk_log_pkey"/>
@ -127,4 +135,34 @@
/>
</changeSet>
<changeSet id="adding-local-repository_location-to-configuration-table" author="vova">
<addColumn tableName="configuration">
<column name="repository_location" type="varchar(1024)" />
</addColumn>
</changeSet>
<changeSet id="adding-files-table" author="vova/jeroen">
<createTable tableName="files">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false" primaryKeyName="files_pkey"/>
</column>
<column name="name" type="varchar(1024)"/>
<column name="type" type="varchar(22)"/>
<column name="date" type="timestamp with time zone"/>
<column name="uploader" type="BIGINT"/>
<column name="parent" type="BIGINT"/>
</createTable>
<addForeignKeyConstraint baseTableName="files" baseColumnNames="uploader"
constraintName="files_uploader_fkey" referencedTableName="user_table"
referencedColumnNames="id"/>
<addForeignKeyConstraint baseTableName="files" baseColumnNames="parent"
constraintName="files_parent_fkey" referencedTableName="order_element"
referencedColumnNames="id"/>
<sql>
UPDATE configuration SET repository_location = '' WHERE id = 404;
</sql>
</changeSet>
</databaseChangeLog>

View file

@ -6,3 +6,6 @@ password ${dataSource.password}
verbose true
dropFirst false
promptOnNonLocalDatabase false
# If there will be an error with checksum use this command:
#clearCheckSums true

View file

@ -126,6 +126,8 @@
</set>
</component>
<property name="repositoryLocation" column="repository_location"/>
</class>
</hibernate-mapping>

View file

@ -16,9 +16,9 @@
<property name="initDate" access="field" column="init_date" />
<property name="deadline" access="field" />
<property name="lastAdvanceMeausurementForSpreading" access="field"
column="last_advance_meausurement_for_spreading" />
column="last_advance_meausurement_for_spreading" />
<property name="dirtyLastAdvanceMeasurementForSpreading" access="field"
column="dirty_last_advance_measurement_for_spreading" />
column="dirty_last_advance_measurement_for_spreading" />
<!-- Indexed the other side -->
<set name="directAdvanceAssignments" access="field" cascade="all,delete-orphan" inverse="true" batch-size="10">
@ -52,34 +52,34 @@
<!-- Inverse navigation from OrderElement to OrderLineGroup -->
<!-- Indexed -->
<many-to-one name="parent"
access="field"
cascade="all"
class="org.libreplan.business.orders.entities.OrderLineGroup"
index="idx_order_element_on_parent"
lazy="false" />
access="field"
cascade="all"
class="org.libreplan.business.orders.entities.OrderLineGroup"
index="idx_order_element_on_parent"
lazy="false" />
<many-to-one name="template"
access="field"
cascade="none"
class="org.libreplan.business.templates.entities.OrderElementTemplate"
index="idx_order_element_on_template"/>
access="field"
cascade="none"
class="org.libreplan.business.templates.entities.OrderElementTemplate"
index="idx_order_element_on_template"/>
<property name="externalCode" access="field" column="external_code" />
<map name="schedulingDatasForVersion" table="scheduling_states_by_order_version"
cascade="all-delete-orphan">
cascade="all-delete-orphan">
<key column="order_element_id"></key>
<map-key-many-to-many column="order_version_id"
class="org.libreplan.business.scenarios.entities.OrderVersion" />
class="org.libreplan.business.scenarios.entities.OrderVersion" />
<many-to-many class="SchedulingDataForVersion"
column="scheduling_state_for_version_id" />
column="scheduling_state_for_version_id" />
</map>
<one-to-one name="sumChargedEffort" class="SumChargedEffort"
cascade="delete" property-ref="orderElement" />
cascade="delete" property-ref="orderElement" />
<one-to-one name="sumExpenses" class="SumExpenses"
cascade="delete" property-ref="orderElement" />
cascade="delete" property-ref="orderElement" />
<joined-subclass name="OrderLineGroup" table="order_line_group">
<key column="order_element_id"></key>
@ -102,11 +102,11 @@
<property name="responsible" access="field" />
<property name="dependenciesConstraintsHavePriority"
column="dependencies_constraints_have_priority" access="field" />
column="dependencies_constraints_have_priority" access="field" />
<property name="codeAutogenerated" column="code_autogenerated"
access="field" />
access="field" />
<property name="lastOrderElementSequenceCode"
column="last_order_element_sequence_code" access="field" />
column="last_order_element_sequence_code" access="field" />
<property name="workBudget" column="work_budget" access="field" />
<property name="materialsBudget" column="materials_budget" access="field" />
@ -134,7 +134,7 @@
<!-- Not indexed -->
<many-to-one name="calendar" column="base_calendar_id" cascade="none"
class="org.libreplan.business.calendars.entities.BaseCalendar"/>
class="org.libreplan.business.calendars.entities.BaseCalendar"/>
<set name="orderAuthorizations" cascade="all-delete-orphan" inverse="true" batch-size="10">
<key column="order_id" />
@ -144,9 +144,9 @@
<map name="scenarios" table="scenario_orders" cascade="save-update">
<key column="order_id" />
<map-key-many-to-many column="scenario_id"
class="org.libreplan.business.scenarios.entities.Scenario" />
class="org.libreplan.business.scenarios.entities.Scenario" />
<many-to-many column="order_version_id"
class="org.libreplan.business.scenarios.entities.OrderVersion"/>
class="org.libreplan.business.scenarios.entities.OrderVersion"/>
</map>
<set name="customerCommunications" cascade="delete-orphan" inverse="true" >
@ -154,16 +154,16 @@
<one-to-many class="org.libreplan.business.externalcompanies.entities.CustomerCommunication" />
</set>
<set name="deliveringDates" inverse="false" cascade="all,delete-orphan" access="field"
sort="org.libreplan.business.externalcompanies.entities.DeliverDateComparator">
<key column="order_id" />
<one-to-many class="org.libreplan.business.externalcompanies.entities.DeadlineCommunication" />
<set name="deliveringDates" inverse="false" cascade="all,delete-orphan" access="field"
sort="org.libreplan.business.externalcompanies.entities.DeliverDateComparator">
<key column="order_id" />
<one-to-many class="org.libreplan.business.externalcompanies.entities.DeadlineCommunication" />
</set>
<set name="endDateCommunicationToCustomer" inverse="false" cascade="all,delete-orphan" access="field"
sort="org.libreplan.business.externalcompanies.entities.EndDateCommunicationComparator">
<key column="order_id" />
<one-to-many class="org.libreplan.business.externalcompanies.entities.EndDateCommunication" />
<set name="endDateCommunicationToCustomer" inverse="false" cascade="all,delete-orphan" access="field"
sort="org.libreplan.business.externalcompanies.entities.EndDateCommunicationComparator">
<key column="order_id" />
<one-to-many class="org.libreplan.business.externalcompanies.entities.EndDateCommunication" />
</set>
</joined-subclass>
@ -179,7 +179,7 @@
</set>
<property name="lastHoursGroupSequenceCode"
column="last_hours_group_sequence_code" access="field" />
column="last_hours_group_sequence_code" access="field" />
<property name="budget" scale="2" access="field" />
</joined-subclass>
@ -214,13 +214,13 @@
<!-- Indexed -->
<many-to-one name="parentOrderLine" column="parent_order_line"
class="org.libreplan.business.orders.entities.OrderLine"
index="idx_hours_group_on_parent_order_line"/>
class="org.libreplan.business.orders.entities.OrderLine"
index="idx_hours_group_on_parent_order_line"/>
<!-- Indexed -->
<many-to-one name="orderLineTemplate" column="order_line_template"
class="org.libreplan.business.templates.entities.OrderLineTemplate"
index="idx_hours_group_on_order_line_template"/>
class="org.libreplan.business.templates.entities.OrderLineTemplate"
index="idx_hours_group_on_order_line_template"/>
</class>
@ -236,7 +236,7 @@
<param name="enumClass">org.libreplan.business.orders.entities.SchedulingState$Type</param>
</type>
</property>
<many-to-one name="orderElement" column="order_element_id"></many-to-one>
<many-to-one name="orderElement" column="order_element_id" lazy="false"></many-to-one>
<one-to-one name="taskSource" class="TaskSource" cascade="delete" access="field" property-ref="schedulingData" />
</class>
@ -248,9 +248,9 @@
</id>
<version name="version" access="property" type="long" />
<many-to-one name="schedulingData" class="SchedulingDataForVersion"
cascade="none" unique="true" access="field" />
cascade="none" unique="true" access="field" lazy="false" />
<one-to-one name="task" class="org.libreplan.business.planner.entities.TaskElement"
constrained="true" cascade="delete" access="field" lazy="false"/>
constrained="true" cascade="delete" access="field" lazy="false"/>
<set name="hoursGroups" table="task_source_hours_groups" cascade="none" inverse="false" access="field" batch-size="10">
<key column="task_source_id"></key>
@ -267,21 +267,21 @@
<version name="version" access="property" type="long" />
<many-to-one name="orderElement" column="order_element"
class="OrderElement" cascade="none" unique="true" />
class="OrderElement" cascade="none" unique="true" />
<property name="directChargedEffort" access="field"
column="direct_charged_effort"
type="org.libreplan.business.workingday.hibernate.EffortDurationType" />
column="direct_charged_effort"
type="org.libreplan.business.workingday.hibernate.EffortDurationType" />
<property name="indirectChargedEffort" access="field"
column="indirect_charged_effort"
type="org.libreplan.business.workingday.hibernate.EffortDurationType" />
column="indirect_charged_effort"
type="org.libreplan.business.workingday.hibernate.EffortDurationType" />
<property name="firstTimesheetDate" access="field"
column="first_timesheet_date" />
column="first_timesheet_date" />
<property name="lastTimesheetDate" access="field"
column="last_timesheet_date" />
column="last_timesheet_date" />
<property name="finishedTimesheets"
column="finished_timesheets" />
column="finished_timesheets" />
</class>
@ -294,7 +294,7 @@
<version name="version" access="property" type="long" />
<many-to-one name="orderElement" column="order_element_id" cascade="none" unique="true"
class="OrderElement" />
class="OrderElement" />
<property name="totalDirectExpenses" access="field" column="total_direct_expenses"/>
<property name="totalIndirectExpenses" access="field" column="total_indirect_expenses"/>
@ -316,4 +316,25 @@
</many-to-one>
</class>
<class name="OrderFile" abstract="true" table="files">
<id name="id" column="id" type="long" access="property">
<generator class="hilo">
<param name="max_lo">100</param>
</generator>
</id>
<property name="name" column="name" not-null="true" />
<property name="type" column="type" not-null="true" />
<property name="date" column="date"/>
<many-to-one name="uploader"
class="org.libreplan.business.users.entities.User" column="uploader" lazy="false"/>
<many-to-one name="parent"
class="org.libreplan.business.orders.entities.OrderElement" column="parent" lazy="false"/>
</class>
</hibernate-mapping>

View file

@ -294,6 +294,7 @@
</build>
<dependencies>
<!-- Jasper Reports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
@ -303,16 +304,19 @@
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
</dependency>
<!-- GPL Jasperreport Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jasperreportcomponent</artifactId>
</dependency>
<!-- GPL Jasperreport Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jfreechartengine</artifactId>
</dependency>
<!-- GPL detailrow Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
@ -331,6 +335,7 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
</dependency>
<!-- Spring Dependency LDAP -->
<dependency>
<groupId>org.springframework.security</groupId>
@ -365,11 +370,13 @@
<groupId>jfree</groupId>
<artifactId>jcommon</artifactId>
</dependency>
<!-- Apache Commons Fileupload (required by ZK) -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<!-- ZK -->
<dependency>
<groupId>org.zkoss.zk</groupId>
@ -383,11 +390,13 @@
<groupId>org.zkoss.zk</groupId>
<artifactId>zk</artifactId>
</dependency>
<!-- LibrePlan ZK Components -->
<dependency>
<groupId>org.libreplan</groupId>
<artifactId>ganttzk</artifactId>
</dependency>
<!-- LibrePlan Business -->
<dependency>
<groupId>org.libreplan</groupId>
@ -434,7 +443,7 @@
<artifactId>servlet-api</artifactId>
</dependency>
<!--Java mail-->
<!-- Java mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
@ -446,6 +455,7 @@
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</dependency>
<!-- CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
@ -463,6 +473,7 @@
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
</dependency>
<!-- ZK Timeplot -->
<dependency>
<groupId>org.zkoss.zkforge</groupId>
@ -472,26 +483,31 @@
<groupId>org.zkoss.zkforge</groupId>
<artifactId>timeplotz</artifactId>
</dependency>
<!-- JGraphT -->
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-jdk1.5</artifactId>
</dependency>
<!-- jqPlot -->
<dependency>
<groupId>br.com.digilabs.jqplot</groupId>
<artifactId>jqplot4java</artifactId>
</dependency>
<!-- MPXJ Library -->
<dependency>
<groupId>net.sourceforge</groupId>
<artifactId>mpxj</artifactId>
</dependency>
<!-- ZK fileupload -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Quartz framework -->
<dependency>
<groupId>org.quartz-scheduler</groupId>

View file

@ -1172,6 +1172,14 @@ public class ConfigurationController extends GenericForwardComposer {
configurationModel.setSecondsPlanningWarning(secondsPlanningWarning);
}
public String getRepositoryLocation(){
return configurationModel.getRepositoryLocation();
}
public void setRepositoryLocation(String location){
configurationModel.setRepositoryLocation(location);
}
public List<Connector> getConnectors() {
return configurationModel.getConnectors();
}

View file

@ -63,6 +63,7 @@ import org.springframework.transaction.annotation.Transactional;
/**
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -538,8 +539,7 @@ public class ConfigurationModel implements IConfigurationModel {
return entitySequences.get(entityName);
}
public void addEntitySequence(EntityNameEnum entityName, String prefix,
Integer digits) {
public void addEntitySequence(EntityNameEnum entityName, String prefix, Integer digits) {
List<EntitySequence> sequences = entitySequences.get(entityName);
EntitySequence entitySequence = EntitySequence.create(prefix,
entityName, digits);
@ -692,6 +692,16 @@ public class ConfigurationModel implements IConfigurationModel {
configuration.setSecondsPlanningWarning(secondsPlanningWarning);
}
@Override
public String getRepositoryLocation() {
return configuration.getRepositoryLocation();
}
@Override
public void setRepositoryLocation(String location) {
configuration.setRepositoryLocation(location);
}
private void saveConnectors() {
for (Connector connector : connectors) {
connectorDAO.save(connector);

View file

@ -37,6 +37,7 @@ import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
* Contract for {@link ConfigurationModel}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/
public interface IConfigurationModel {
@ -102,8 +103,7 @@ public interface IConfigurationModel {
List<EntitySequence> getEntitySequences(EntityNameEnum entityName);
void addEntitySequence(EntityNameEnum entityName, String prefix,
Integer digits);
void addEntitySequence(EntityNameEnum entityName, String prefix, Integer digits);
void removeEntitySequence(EntitySequence entitySequence)
throws IllegalArgumentException;
@ -186,6 +186,10 @@ public interface IConfigurationModel {
void setSecondsPlanningWarning(
Integer planningWarningExitWithoutSavingSeconds);
String getRepositoryLocation();
void setRepositoryLocation(String location);
List<Connector> getConnectors();
Connector getConnectorByName(String name);

View file

@ -52,17 +52,7 @@ public class EmailNotificationModel implements IEmailNotificationModel {
@Autowired
private IEmailNotificationDAO emailNotificationDAO;
private EmailTemplateEnum type;
private Date updated;
private Resource resource;
private TaskElement task;
private TaskElement project;
private EmailNotification emailNotification = new EmailNotification();
private EmailNotification emailNotification;
@Override
@Transactional
@ -76,12 +66,29 @@ public class EmailNotificationModel implements IEmailNotificationModel {
return emailNotificationDAO.getAll();
}
@Override
@Transactional
public List<EmailNotification> getAllByType(EmailTemplateEnum enumeration) {
return emailNotificationDAO.getAllByType(enumeration);
}
@Override
@Transactional
public boolean deleteAll() {
return emailNotificationDAO.deleteAll();
}
@Override
public boolean deleteAllByType(EmailTemplateEnum enumeration) {
return emailNotificationDAO.deleteAllByType(enumeration);
}
@Override
@Transactional
public boolean deleteById(EmailNotification notification){
return emailNotificationDAO.deleteById(notification);
}
@Override
public void setType(EmailTemplateEnum type) {
this.emailNotification.setType(type);
@ -107,4 +114,13 @@ public class EmailNotificationModel implements IEmailNotificationModel {
this.emailNotification.setProject(project);
}
public EmailNotification getEmailNotification() {
return emailNotification;
}
public void setNewObject(){
this.emailNotification = new EmailNotification();
}
}

View file

@ -75,8 +75,7 @@ public class EmailTemplateController extends GenericForwardComposer{
public static ListitemRenderer languagesRenderer = new ListitemRenderer() {
@Override
public void render(org.zkoss.zul.Listitem item, Object data)
throws Exception {
public void render(Listitem item, Object data) throws Exception {
Language language = (Language) data;
String displayName = language.getDisplayName();
item.setLabel(displayName);
@ -90,7 +89,7 @@ public class EmailTemplateController extends GenericForwardComposer{
messages = new MessagesForUser(messagesContainer);
// Set default template and language for user
// And content and subject for it
// And content and subject for that language & template
setUser();
setSelectedLanguage(user.getApplicationLanguage());
@ -108,7 +107,9 @@ public class EmailTemplateController extends GenericForwardComposer{
return true;
} catch (ValidationException e) {
messages.showInvalidValues(e);
} catch (InstanceNotFoundException e) {}
} catch (InstanceNotFoundException e) {
e.printStackTrace();
}
return false;
}
@ -193,7 +194,7 @@ public class EmailTemplateController extends GenericForwardComposer{
subjectTextbox.setValue(emailTemplateModel.getSubjectBySelectedLanguage(getSelectedLanguage().ordinal(), getSelectedEmailTemplateEnum().ordinal()));
}
private void getSubjectDataBySelectedTemplate(){
subjectTextbox.setValue( emailTemplateModel.getContentBySelectedTemplate(getSelectedEmailTemplateEnum().ordinal(), getSelectedLanguage().ordinal()) );
subjectTextbox.setValue( emailTemplateModel.getSubjectBySelectedTemplate(getSelectedEmailTemplateEnum().ordinal(), getSelectedLanguage().ordinal()) );
}
@Transactional

View file

@ -24,10 +24,7 @@ import org.libreplan.business.settings.entities.Language;
import org.libreplan.business.email.daos.IEmailTemplateDAO;
import org.libreplan.business.email.entities.EmailTemplate;
import org.libreplan.business.email.entities.EmailTemplateEnum;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.business.users.entities.User;
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
import org.libreplan.web.security.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@ -51,26 +48,13 @@ public class EmailTemplateModel implements IEmailTemplateModel {
@Autowired
private IEmailTemplateDAO emailTemplateDAO;
@Autowired
private IUserDAO userDAO;
private Language language = Language.ENGLISH_LANGUAGE;
private EmailTemplateEnum emailTemplateEnum = EmailTemplateEnum.TEMPLATE_TASK_ASSIGNED_TO_RESOURCE;
private String content;
private String subject;
private User user;
private EmailTemplate emailTemplate = new EmailTemplate();
@Override
@Transactional
public void confirmSave() throws InstanceNotFoundException {
/* If current EmailTemplate entity (id) is existing in DB than it needs to update.
/* If current EmailTemplate entity (id) is existing in DB than it needs to be updated.
* Else current EmailTemplate entity (id) is creating and getting new values from form.
*/
List<EmailTemplate> emailTemplates = emailTemplateDAO.getAll();

View file

@ -40,8 +40,11 @@ public interface IEmailNotificationModel {
void confirmSave() throws ValidationException;
List<EmailNotification> getAll();
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
boolean deleteAll();
boolean deleteAllByType(EmailTemplateEnum enumeration);
boolean deleteById(EmailNotification notification);
void setType(EmailTemplateEnum type);
void setUpdated(Date date);
@ -49,4 +52,7 @@ public interface IEmailNotificationModel {
void setTask(TaskElement task);
void setProject(TaskElement project);
EmailNotification getEmailNotification();
void setNewObject();
}

View file

@ -72,6 +72,7 @@ import org.libreplan.web.common.components.finders.FilterPair;
import org.libreplan.web.common.components.finders.OrderFilterEnum;
import org.libreplan.web.common.components.finders.TaskGroupFilterEnum;
import org.libreplan.web.orders.criterionrequirements.AssignedCriterionRequirementToOrderElementController;
import org.libreplan.web.orders.files.OrderFilesController;
import org.libreplan.web.orders.labels.AssignedLabelsToOrderElementController;
import org.libreplan.web.orders.labels.LabelsAssignmentToOrderElementComponent;
import org.libreplan.web.orders.materials.AssignedMaterialsToOrderElementController;
@ -278,17 +279,17 @@ public class OrderCRUDController extends GenericForwardComposer {
List<FilterPair> sessionFilters = FilterUtils
.readProjectsParameters();
// Allow labels when list is empty
if (sessionFilters != null) {
if ( sessionFilters != null ) {
bdFilters.addSelectedElements(toOrderFilterEnum(sessionFilters));
return;
}
User user = orderModel.getUser();
// Calculate filter based on user preferences
if ((user != null) && (user.getProjectsFilterLabel() != null)) {
if ( (user != null) && (user.getProjectsFilterLabel() != null) ) {
bdFilters.addSelectedElement(new FilterPair(OrderFilterEnum.Label,
user.getProjectsFilterLabel().getFinderPattern(), user
.getProjectsFilterLabel()));
user.getProjectsFilterLabel().getFinderPattern(),
user.getProjectsFilterLabel()));
}
}
@ -298,23 +299,23 @@ public class OrderCRUDController extends GenericForwardComposer {
TaskGroupFilterEnum type = (TaskGroupFilterEnum) filterPair
.getType();
switch (type) {
case Label:
result.add(new FilterPair(OrderFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
case Criterion:
result.add(new FilterPair(OrderFilterEnum.Criterion, filterPair
.getPattern(), filterPair.getValue()));
break;
case ExternalCompany:
result.add(new FilterPair(OrderFilterEnum.ExternalCompany,
filterPair.getPattern(), filterPair.getValue()));
break;
case State:
result.add(new FilterPair(OrderFilterEnum.State, filterPair
.getPattern(), filterPair.getValue()));
break;
default:
case Label:
result.add(new FilterPair(OrderFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
case Criterion:
result.add(new FilterPair(OrderFilterEnum.Criterion, filterPair
.getPattern(), filterPair.getValue()));
break;
case ExternalCompany:
result.add(new FilterPair(OrderFilterEnum.ExternalCompany,
filterPair.getPattern(), filterPair.getValue()));
break;
case State:
result.add(new FilterPair(OrderFilterEnum.State, filterPair
.getPattern(), filterPair.getValue()));
break;
default:
}
}
return result;
@ -452,8 +453,7 @@ public class OrderCRUDController extends GenericForwardComposer {
});
}
private Comboitem createCombo(Object value, String label,
String description) {
private Comboitem createCombo(Object value, String label, String description) {
Comboitem result = new Comboitem();
result.setValue(value);
result.setLabel(label);
@ -646,7 +646,7 @@ public class OrderCRUDController extends GenericForwardComposer {
if (assignedLabelsController == null) {
LabelsAssignmentToOrderElementComponent labelsAssignment = (LabelsAssignmentToOrderElementComponent) editWindow
.getFellow("orderElementLabels");
.getFellow("orderElementLabels");
assignedLabelsController = labelsAssignment.getController();
final IOrderElementModel orderElementModel = getOrderElementModel();
@ -664,9 +664,9 @@ public class OrderCRUDController extends GenericForwardComposer {
if (assignedCriterionRequirementController == null) {
Component orderElementCriterionRequirements = editWindow
.getFellowIfAny("orderElementCriterionRequirements");
.getFellowIfAny("orderElementCriterionRequirements");
assignedCriterionRequirementController = (AssignedCriterionRequirementToOrderElementController) orderElementCriterionRequirements
.getVariable("assignedCriterionRequirementController", true);
.getVariable("assignedCriterionRequirementController", true);
final IOrderElementModel orderElementModel = getOrderElementModel();
assignedCriterionRequirementController
@ -686,7 +686,7 @@ public class OrderCRUDController extends GenericForwardComposer {
if (assignedMaterialsController == null) {
OrderElementMaterialAssignmentsComponent assignmentsComponent = (OrderElementMaterialAssignmentsComponent) editWindow
.getFellowIfAny("orderElementMaterials");
.getFellowIfAny("orderElementMaterials");
assignedMaterialsController = assignmentsComponent.getController();
final IOrderElementModel orderElementModel = getOrderElementModel();
@ -707,7 +707,7 @@ public class OrderCRUDController extends GenericForwardComposer {
.getFellowIfAny("orderElementTaskQualityForms");
if (assignedTaskQualityFormController == null) {
assignedTaskQualityFormController = (AssignedTaskQualityFormsToOrderElementController) orderElementTaskQualityForms
.getVariable("assignedTaskQualityFormsController", true);
.getVariable("assignedTaskQualityFormsController", true);
final IOrderElementModel orderElementModel = getOrderElementModel();
assignedTaskQualityFormController.openWindow(orderElementModel);
} else {
@ -716,6 +716,29 @@ public class OrderCRUDController extends GenericForwardComposer {
}
}
private OrderFilesController orderFilesController;
public void setupOrderFilesController(){
if ( !confirmLastTab() ){
return;
}
setCurrentTab();
Component orderFiles = editWindow.getFellowIfAny("orderElementFiles");
if ( orderFilesController == null ){
orderFilesController = (OrderFilesController) orderFiles
.getVariable("orderFilesController", true);
final IOrderElementModel orderElementModel = getOrderElementModel();
orderFilesController.openWindow(orderElementModel);
} else {
}
}
private OrderAuthorizationController orderAuthorizationController;
public void setupOrderAuthorizationController() {
@ -771,29 +794,29 @@ public class OrderCRUDController extends GenericForwardComposer {
.getSelectedElements()) {
OrderFilterEnum type = (OrderFilterEnum) filterPair.getType();
switch (type) {
case Label:
labels.add((org.libreplan.business.labels.entities.Label) filterPair
.getValue());
break;
case Criterion:
criteria.add((Criterion) filterPair.getValue());
break;
case ExternalCompany:
if (customer != null) {
// It's impossible to have an Order associated to more than
// 1 customer
return Collections.emptyList();
}
customer = (ExternalCompany) filterPair.getValue();
break;
case State:
if (state != null) {
// It's impossible to have an Order associated with more
// than 1 state
return Collections.emptyList();
}
state = (OrderStatusEnum) filterPair.getValue();
break;
case Label:
labels.add((org.libreplan.business.labels.entities.Label) filterPair
.getValue());
break;
case Criterion:
criteria.add((Criterion) filterPair.getValue());
break;
case ExternalCompany:
if (customer != null) {
// It's impossible to have an Order associated to more than
// 1 customer
return Collections.emptyList();
}
customer = (ExternalCompany) filterPair.getValue();
break;
case State:
if (state != null) {
// It's impossible to have an Order associated with more
// than 1 state
return Collections.emptyList();
}
state = (OrderStatusEnum) filterPair.getValue();
break;
}
}
@ -862,7 +885,7 @@ public class OrderCRUDController extends GenericForwardComposer {
private void refreshCodeTextboxesOnly() {
if (orderElementTreeController != null) {
Map<OrderElement, Textbox> orderElementCodeTextBoxes =
orderElementTreeController.getOrderElementCodeTextboxes();
orderElementTreeController.getOrderElementCodeTextboxes();
for (OrderElement element : orderElementCodeTextBoxes.keySet()) {
if (element.getId() != null) {
@ -1423,10 +1446,9 @@ public class OrderCRUDController extends GenericForwardComposer {
public void validate(Component comp, Object value)
throws WrongValueException {
Date finishDate = (Date) value;
if ((finishDate != null)
if ( (finishDate != null)
&& (filterStartDate.getRawValue() != null)
&& (finishDate.compareTo((Date) filterStartDate
.getRawValue()) < 0)) {
&& (finishDate.compareTo((Date) filterStartDate.getRawValue()) < 0) ) {
throw new WrongValueException(comp,
_("must be after start date"));
}
@ -1440,11 +1462,9 @@ public class OrderCRUDController extends GenericForwardComposer {
public void validate(Component comp, Object value)
throws WrongValueException {
Date startDate = (Date) value;
if ((startDate != null)
if ( (startDate != null)
&& (filterFinishDate.getRawValue() != null)
&& (startDate.compareTo((Date) filterFinishDate
.getRawValue()) > 0)) {
// filterStartDate.setValue(null);
&& (startDate.compareTo((Date) filterFinishDate.getRawValue()) > 0) ) {
throw new WrongValueException(comp,
_("must be lower than end date"));
}
@ -1480,26 +1500,26 @@ public class OrderCRUDController extends GenericForwardComposer {
OrderFilterEnum type = (OrderFilterEnum) filterPair
.getType();
switch (type) {
case Label:
result.add(new FilterPair(TaskGroupFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
case Criterion:
result.add(new FilterPair(TaskGroupFilterEnum.Criterion,
filterPair.getPattern(), filterPair.getValue()));
break;
case ExternalCompany:
result.add(new FilterPair(TaskGroupFilterEnum.ExternalCompany,
filterPair.getPattern(), filterPair.getValue()));
break;
case State:
result.add(new FilterPair(TaskGroupFilterEnum.State, filterPair
.getPattern(), filterPair.getValue()));
break;
default:
result.add(new FilterPair(OrderFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
case Label:
result.add(new FilterPair(TaskGroupFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
case Criterion:
result.add(new FilterPair(TaskGroupFilterEnum.Criterion,
filterPair.getPattern(), filterPair.getValue()));
break;
case ExternalCompany:
result.add(new FilterPair(TaskGroupFilterEnum.ExternalCompany,
filterPair.getPattern(), filterPair.getValue()));
break;
case State:
result.add(new FilterPair(TaskGroupFilterEnum.State, filterPair
.getPattern(), filterPair.getValue()));
break;
default:
result.add(new FilterPair(OrderFilterEnum.Label, filterPair
.getPattern(), filterPair.getValue()));
break;
}
}
return result;
@ -1582,7 +1602,7 @@ public class OrderCRUDController extends GenericForwardComposer {
if (!(orderElement instanceof Order)
&& orderElementTreeController != null) {
final Treeitem item = orderElementTreeController
.getTreeitemByOrderElement(orderElement);
.getTreeitemByOrderElement(orderElement);
if (item != null) {
orderElementTreeController
@ -1641,7 +1661,7 @@ public class OrderCRUDController extends GenericForwardComposer {
public SortedSet<DeadlineCommunication> getDeliverDates() {
if(getOrder() != null){
return getOrder().getDeliveringDates();
return getOrder().getDeliveringDates();
}
return new TreeSet<DeadlineCommunication>(new DeliverDateComparator());
}
@ -1870,12 +1890,10 @@ public class OrderCRUDController extends GenericForwardComposer {
public BigDecimal getResourcesBudget() {
return Registry.getTransactionService().runOnReadOnlyTransaction(
new IOnTransaction<BigDecimal>() {
@Override
public BigDecimal execute() {
return getOrderElementModel().getOrderElement()
.getResourcesBudget();
new IOnTransaction<BigDecimal>() {
@Override
public BigDecimal execute() {
return getOrderElementModel().getOrderElement().getResourcesBudget();
}
});
}

View file

@ -0,0 +1,40 @@
package org.libreplan.web.orders.files;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import org.libreplan.business.users.entities.User;
import java.util.Date;
import java.util.List;
/**
* Contract for {@link OrderFile}
*
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/
public interface IOrderFileModel {
void confirmSave();
void setFileName(String name);
void setFileType(String type);
void setUploadDate(Date date);
void setUploader(User user);
void setParent(OrderElement project);
void createNewFileObject();
List<OrderFile> getAll();
void delete(OrderFile file);
List<OrderFile> findByParent(OrderElement parent);
OrderFile getOrderFile();
}

View file

@ -0,0 +1,88 @@
package org.libreplan.web.orders.files;
import org.libreplan.business.orders.daos.IOrderFileDAO;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import org.libreplan.business.users.entities.User;
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.Date;
import java.util.List;
/**
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderFileModel implements IOrderFileModel {
@Autowired
private IOrderFileDAO fileDAO;
private OrderFile orderFile;
@Override
@Transactional
public void confirmSave() {
fileDAO.save(orderFile);
}
@Override
public void setFileName(String name) {
orderFile.setName(name);
}
@Override
public void setFileType(String type) {
orderFile.setType(type);
}
@Override
public void setUploadDate(Date date) {
orderFile.setDate(date);
}
@Override
public void setUploader(User user) {
orderFile.setUploader(user);
}
@Override
public void setParent(OrderElement project) {
orderFile.setParent(project);
}
@Override
public void createNewFileObject() {
orderFile = new OrderFile();
}
@Override
@Transactional
public List<OrderFile> getAll() {
return fileDAO.getAll();
}
@Override
@Transactional
public void delete(OrderFile file){
fileDAO.delete(file);
}
@Override
@Transactional
public List<OrderFile> findByParent(OrderElement parent) {
return fileDAO.findByParent(parent);
}
public OrderFile getOrderFile() {
return orderFile;
}
}

View file

@ -0,0 +1,297 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2016 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.orders.files;
import org.apache.commons.io.FilenameUtils;
import org.hibernate.engine.jdbc.ReaderInputStream;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.web.common.IConfigurationModel;
import org.libreplan.web.common.IMessagesForUser;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.Util;
import org.libreplan.web.common.MessagesForUser;
import org.libreplan.web.orders.IOrderElementModel;
import org.libreplan.web.security.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Fileupload;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Label;
import org.zkoss.zul.Filedownload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.libreplan.web.I18nHelper._;
/**
* Controller for managing Order files
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 12.24.2015.
*/
public class OrderFilesController extends GenericForwardComposer {
@Autowired
IConfigurationModel configurationModel;
@Autowired
IUserDAO userDAO;
private Component messagesContainer;
private IMessagesForUser messages;
private IOrderElementModel orderElementModel;
private IOrderFileModel orderFileModel;
private Listbox filesList;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
comp.setVariable("orderFilesController", this, true);
messages = new MessagesForUser(messagesContainer);
}
public boolean isRepositoryExists() {
configurationModel.init();
File repositoryDirectory = null;
if ( !(configurationModel.getRepositoryLocation() == null) )
repositoryDirectory = new File(configurationModel.getRepositoryLocation());
if ( repositoryDirectory != null && repositoryDirectory.exists() ) return true;
return false;
}
public boolean isUploadButtonDisabled(){
if ( isRepositoryExists() ) return false;
return true;
}
public ListitemRenderer getFilesRenderer(){
return new ListitemRenderer() {
@Override
public void render(Listitem listitem, Object data) throws Exception {
final OrderFile file = (OrderFile) data;
Listcell nameCell = new Listcell();
listitem.appendChild(nameCell);
Label label = new Label(file.getName());
label.addEventListener("onClick", new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
configurationModel.init();
String projectCode = orderElementModel.getOrderElement().getCode();
String directory = configurationModel.getRepositoryLocation() + "orders" + "/" + projectCode;
File fileToDownload = new File(directory + "/" + file.getName() + "." + file.getType());
Filedownload.save(fileToDownload.getAbsoluteFile(), null);
}
});
label.setClass("label-highlight");
label.setTooltiptext("Download file");
nameCell.appendChild(label);
Listcell typeCell = new Listcell();
listitem.appendChild(typeCell);
typeCell.appendChild(new Label(file.getType()));
Listcell dateCell = new Listcell();
listitem.appendChild(dateCell);
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
dateCell.appendChild(new Label(sdf.format(file.getDate())));
Listcell uploaderCell = new Listcell();
listitem.appendChild(uploaderCell);
uploaderCell.appendChild(new Label(file.getUploader().getLoginName()));
Listcell operationsCell = new Listcell();
listitem.appendChild(operationsCell);
operationsCell.appendChild(Util.createRemoveButton(new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
confirmRemove(file);
}
}));
}
};
}
public void confirmRemove(OrderFile file){
try {
int status = Messagebox.show(_("Confirm deleting this file. Are you sure?"), _("Delete"),
Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
if ( Messagebox.OK != status ) {
return;
}
} catch (InterruptedException e) {}
if ( isRepositoryExists() ) {
String projectCode = orderElementModel.getOrderElement().getCode();
configurationModel.init();
String directory = configurationModel.getRepositoryLocation() + "orders" + "/" + projectCode;
File fileToDelete = new File(directory + "/" + file.getName() + "." + file.getType());
boolean deleted = fileToDelete.delete();
if ( deleted ){
orderFileModel.delete(file);
messages.clearMessages();
messages.showMessage(Level.INFO, "File successfully deleted");
updateListbox();
} else {
messages.clearMessages();
messages.showMessage(Level.ERROR, "Error while deleting");
}
} else {
messages.clearMessages();
messages.showMessage(Level.ERROR, "Repository not created");
}
}
public void upload() {
configurationModel.init();
String directory = "";
if ( isRepositoryExists() ){
String projectCode = orderElementModel.getOrderElement().getCode();
directory = configurationModel.getRepositoryLocation() + "orders" + "/" + projectCode;
try {
Fileupload fileupload = new Fileupload();
// Location of file: libreplan-webapp/src/main/webapp/planner/fileupload.zul
fileupload.setTemplate("fileupload.zul");
Media media = fileupload.get();
File dir = new File(directory);
String filename = media.getName();
File file = new File(dir, filename);
// By default Java do not create directories itself
file.getParentFile().mkdirs();
OutputStream outputStream = new FileOutputStream(file);
InputStream inputStream = media.isBinary() ? (media.getStreamData()) :
(new ReaderInputStream(media.getReaderData()));
if ( inputStream != null ){
byte[] buffer = new byte[1024];
for ( int count; (count = inputStream.read(buffer)) != -1; )
outputStream.write(buffer, 0, count);
}
outputStream.flush();
outputStream.close();
inputStream.close();
orderFileModel.createNewFileObject();
orderFileModel.setFileName(FilenameUtils.getBaseName(media.getName()));
orderFileModel.setFileType(FilenameUtils.getExtension(media.getName()));
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader(userDAO.findByLoginName(SecurityUtils.getSessionUserLoginName()));
orderFileModel.setParent(orderElementModel.getOrderElement());
orderFileModel.confirmSave();
} catch (Exception e){
e.printStackTrace();
}
finally {
updateListbox();
}
} else messages.showMessage(Level.ERROR, _("Please, make repository"));
}
/**
* This method is a:
* 1. setter for current opened {@link org.libreplan.business.orders.entities.Order}
* 2. setter for model of ListBox of files
*
* The easiest way is to set a model in zul file, but its setter was invoking before
* setter of current {@link org.libreplan.business.orders.entities.Order}
*/
public void openWindow(IOrderElementModel orderElementModel) {
setOrderElementModel(orderElementModel);
if ( isRepositoryExists() ) updateListbox();
}
/**
* Listbox is updating after re set the model for it
*/
public void updateListbox(){
OrderElement currentOrder = orderElementModel.getOrderElement();
filesList.setModel(new ListModelList(orderFileModel.findByParent(currentOrder)));
}
public IOrderElementModel getOrderElementModel() {
return orderElementModel;
}
public void setOrderElementModel(IOrderElementModel orderElementModel) {
this.orderElementModel = orderElementModel;
}
}

View file

@ -626,7 +626,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
public boolean isCreateButtonDisabled(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
Integer resourcesCount = resourceDAO.getRowCount().intValue();
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
@ -637,7 +637,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
public String getShowCreateFormLabel(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
Integer resourcesCount = resourceDAO.getRowCount().intValue();
int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )

View file

@ -1172,7 +1172,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
public boolean isCreateButtonDisabled(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
Integer resourcesCount = resourceDAO.getRowCount().intValue();
if ( resourcesTypeLimit != null )
if ( resourcesCount >= resourcesTypeLimit.getValue() )
@ -1183,7 +1183,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
public String getShowCreateFormLabel(){
Limits resourcesTypeLimit = limitsModel.getResourcesType();
Integer resourcesCount = (Integer) resourceDAO.getRowCount();
Integer resourcesCount = resourceDAO.getRowCount().intValue();
int resourcesLeft = resourcesTypeLimit.getValue() - resourcesCount;
if ( resourcesTypeLimit != null )

View file

@ -505,7 +505,7 @@ public class UserCRUDController extends BaseCRUDController<User> implements
public boolean isCreateButtonDisabled(){
Limits usersTypeLimit = limitsModel.getUsersType();
Integer usersCount = (Integer) userModel.getRowCount();
Integer usersCount = userModel.getRowCount().intValue();
if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() )
return true;
@ -514,7 +514,7 @@ public class UserCRUDController extends BaseCRUDController<User> implements
public String getShowCreateFormLabel(){
Limits usersTypeLimit = limitsModel.getUsersType();
Integer usersCount = (Integer) userModel.getRowCount();
Integer usersCount = userModel.getRowCount().intValue();
int usersLeft = usersTypeLimit.getValue() - usersCount;
if (usersTypeLimit != null)
if ( usersCount >= usersTypeLimit.getValue() )

View file

@ -145,6 +145,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/qualityforms/_listQualityForm.zul:38
#: libreplan-webapp/src/main/webapp/qualityforms/_editQualityForm.zul:87
#: libreplan-webapp/src/main/webapp/limitingresources/limitingResourcesLayout.zul:143
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:40
msgid "Operations"
msgstr ""
@ -3547,6 +3548,7 @@ msgid "Unschedule"
msgstr ""
#: libreplan-webapp/src/main/webapp/users/_editUser.zul:36
#: libreplan-webapp/src/main/webapp/email/email_template.zul:42
msgid "General user data"
msgstr ""
@ -4648,6 +4650,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/qualityforms/_editQualityForm.zul:42
#: libreplan-webapp/src/main/webapp/qualityforms/_editQualityForm.zul:83
#: libreplan-webapp/src/main/webapp/limitingresources/limitingResourcesLayout.zul:96
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:36
msgid "Name"
msgstr ""
@ -8129,6 +8132,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul:47
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul:153
#: libreplan-webapp/src/main/webapp/advance/_editAdvanceTypes.zul:62
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:37
msgid "Type"
msgstr ""
@ -8760,6 +8764,7 @@ msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementCriterionRequirements.zul:212
#: libreplan-webapp/src/main/webapp/qualityforms/_listQualityForm.zul:52
#: libreplan-webapp/src/main/webapp/qualityforms/_editQualityForm.zul:116
#: libreplan-webapp/src/main/java/org/libreplan/web/orders/files/OrderFilesController.java:148
msgid "Delete"
msgstr ""
@ -9226,6 +9231,7 @@ msgid "Task assigned to resource"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/common/CustomMenuController.java:425
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:91
msgid "Edit E-mail Templates"
msgstr ""
@ -9314,3 +9320,43 @@ msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java:247
msgid "Check fields"
msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_edition.zul:59
msgid "Files"
msgstr ""
#: libreplan-business/src/main/java/org/libreplan/business/users/entities/UserRole.java:92
msgid "Use files for order"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/orders/files/OrderFilesController.java:252
msgid "Please, make repository"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/orders/files/OrderFilesController.java:148
msgid "Confirm deleting this file. Are you sure?"
msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:26
msgid "Upload"
msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:38
msgid "Upload date"
msgstr ""
#: libreplan-webapp/src/main/webapp/orders/_listOrderElementFiles.zul:39
msgid "Uploaded by"
msgstr ""
#: libreplan-webapp/src/main/webapp/email/email_template.zul:50
msgid "Select template language"
msgstr ""
#: libreplan-webapp/src/main/webapp/email/email_template.zul:59
msgid "Select template type"
msgstr ""
#: libreplan-webapp/src/main/webapp/common/configuration.zul:240
msgid "Local document repository location"
msgstr ""

View file

@ -236,6 +236,14 @@
value="${i18n:_('Defines the time since last saving operation at project planning perspectives after which a warning is raised on leaving. Set to 0 in order to disable the warning.')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Local document repository location')}"/>
<textbox id="repoLocation" width="300px"
tooltiptext="Example: /example/repository/path/"
value="@{configurationController.repositoryLocation}"
constraint="/(\/.*\/$|^$)/:Example: example/repository/path/"
/>
</row>
</rows>
</grid>
</tabpanel>

View file

@ -1,5 +1,6 @@
<window apply="org.libreplan.web.dashboard.DashboardControllerGlobal" contentStyle="overflow:auto;">
<checkbox id="storedColumnVisible" label="${i18n:_('Show archived column data')}" checked="true" onCheck="dashboardControllerGlobal.showStoredColumn()"/>
<checkbox id="storedColumnVisible" label="${i18n:_('Show archived column data')}"
checked="true" onCheck="dashboardControllerGlobal.showStoredColumn()"/>
<grid id="pipelineGrid" sclass="global-dashboard-grid">
<columns>

View file

@ -39,7 +39,7 @@
<tabpanels>
<tabpanel>
<groupbox>
<caption label="General user data" />
<caption label="${i18n:_('General user data')}" />
<grid>
<columns>
<column width="220px"></column>
@ -47,7 +47,7 @@
</columns>
<rows>
<row>
<label value="Select template language"/>
<label value="${i18n:_('Select template language')}"/>
<listbox mold="select"
id="templateLanguageListbox"
model="@{emailTemplateController.languages}"
@ -56,7 +56,7 @@
</listbox>
</row>
<row>
<label value="Select template type"/>
<label value="${i18n:_('Select template type')}"/>
<listbox id="emailTemplateTypeListbox"
mold="select"
model="@{emailTemplateController.emailTemplateEnum}"

View file

@ -32,6 +32,7 @@
macroURI="/orders/components/_listOrderElementMaterials.zul"?>
<?component name="listOrderElementTaskQualityForms" inline="true" macroURI="_listOrderElementTaskQualityForms.zul"?>
<?component name="listOrderElementAuthorizations" inline="true" macroURI="_listOrderElementAuthorizations.zul"?>
<?component name="listOrderElementFiles" inline="true" macroURI="_listOrderElementFiles.zul"?>
<?component name="jiraOrderElementSynchronizer" inline="true" macroURI="components/_jiraOrderElementSync.zul"?>
<?component name="timOrderTimesheetSynchronizer" inline="true" macroURI="components/_timOrderTimesheetSync.zul"?>
@ -56,6 +57,8 @@
onSelect = "controller.setupAssignedMaterialsToOrderElementController();"/>
<tab id="tabTaskQualityForm" label="${i18n:_('Task quality forms')}"
onSelect = "controller.setupAssignedTaskQualityFormsToOrderElementController();"/>
<tab id="tabFiles" label="${i18n:_('Files')}"
onSelect="controller.setupOrderFilesController();"/>
<tab id="tabAuthorizations" label="${i18n:_('Authorizations')}"
onSelect = "controller.setupOrderAuthorizationController();"/>
</tabs>
@ -334,6 +337,9 @@
<tabpanel>
<listOrderElementTaskQualityForms id="orderElementTaskQualityForms" fulfill="tabTaskQualityForm.onSelect"/>
</tabpanel>
<tabpanel>
<listOrderElementFiles id="orderElementFiles" fulfill="tabFiles.onSelect"/>
</tabpanel>
<tabpanel>
<listOrderElementAuthorizations id="orderElementAuthorizations" fulfill="tabAuthorizations.onSelect"/>
</tabpanel>

View file

@ -0,0 +1,43 @@
<!--
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/>.
-->
<window id="orderElementFiles" apply="org.libreplan.web.orders.files.OrderFilesController" width="100%">
<vbox id="messagesContainer">
</vbox>
<button label="${i18n:_('Upload')}" disabled="@{orderFilesController.isUploadButtonDisabled}"
onClick="orderFilesController.upload();"/>
<separator spacing="15px"/>
<listbox id="filesList"
width="99%"
visible="@{orderFilesController.isRepositoryExists}"
itemRenderer="@{orderFilesController.filesRenderer}">
<listhead>
<listheader label="${i18n:_('Name')}" width="62%"/>
<listheader label="${i18n:_('Type')}" width="7%"/>
<listheader label="${i18n:_('Upload date')}" width="11%"/>
<listheader label="${i18n:_('Uploaded by')}" width="13%"/>
<listheader label="${i18n:_('Operations')}" width="7%"/>
</listhead>
</listbox>
</window>

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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/>.
-->
<!--
fileuploaddlg.zul
Purpose:
The fileupload modal dialog
Description:
History:
Tue Jul 19 12:06:22 2005, Created by tomyeh
Copyright (C) 2005 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
-->
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?>
<?page language="xul/html"?>
<?component name="uploaddlg" extends="window"
class="org.zkoss.zul.impl.FileuploadDlg" widgetClass="zul.fud.FileuploadDlg"?>
<?component name="submit" extends="button" widgetClass="zul.fud.Submit"?>
<?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n"?>
<uploaddlg title="${arg.title}" shadow="false" border="normal" width="360px" closable="true"
xmlns:w="http://www.zkoss.org/2005/zk/client"
w:onClose="this.cancel()" w:max="${arg.max}">
<label value="${i18n:_('Please select a file on your system')}"/>
<fileupload id="fileupload" forward="onUpload=" label="${c:l('mesg:org.zkoss.zul.mesg.MZul:UPLOAD_BROWSE')}"
upload="zul.fud.ModalFileViewer,maxsize=${arg.maxsize}${arg.native ? ',native':''}"/>
<separator bar="true"/>
<div id="uploaded" visible="false"></div>
<div id="btns">
<submit id="submit" label="${c:l('mesg:org.zkoss.zul.mesg.MZul:UPLOAD_SUBMIT')}"
w:onClick="this.submit()"/>
<button label="${c:l('mesg:org.zkoss.zul.mesg.MZul:UPLOAD_CANCEL')}" w:onClick="this.$o().cancel(true)"/>
</div>
</uploaddlg>

View file

@ -0,0 +1,269 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2016 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.orders;
import org.hibernate.PropertyValueException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE;
import org.hibernate.Transaction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.libreplan.business.orders.entities.HoursGroup;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderFile;
import org.libreplan.business.orders.entities.OrderLine;
import org.libreplan.business.users.entities.User;
import org.libreplan.web.orders.files.IOrderFileModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Date;
import java.util.List;
/**
* Tests for {@link OrderFile}.
* Created by
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
* on 11.01.2016.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
public class OrderFilesTest {
@Autowired
private IOrderFileModel orderFileModel;
@Autowired
private IOrderElementModel orderElementModel;
@Autowired
private SessionFactory sessionFactory;
private Session newSession;
private Transaction transaction;
/**
* A new session is opened because there was a lot of errors with {@link Transaction}, {@link Session}
*
* CRUD test
* 1. Add row to files table
* 2. Add row and read it
* 3. Add row and update added row
* 4. Add row and delete it
*
* Negative test
* 1. Create row with null field value and try to save it
*/
@Test
public void testRead() {
// This initialize method is for all test methods
initialize();
// Make OrderFile
orderFileModel.createNewFileObject();
orderFileModel.setFileName("noname");
orderFileModel.setFileType(".htaccess");
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader( (User) newSession.createCriteria(User.class).list().get(0) );
orderFileModel.setParent( (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0) );
newSession.save(orderFileModel.getOrderFile());
transactionBeginCommit();
List<OrderFile> file = orderFileModel.getAll();
assertEquals(file.get(0).getName(), "noname");
// Clean data
OrderFile orderFile = (OrderFile) newSession.createCriteria(OrderFile.class).list().get(0);
newSession.delete(orderFile);
transactionBeginCommit();
newSession.close();
}
@Test
public void testCreate(){
newSession = sessionFactory.openSession();
int sizeBefore = orderFileModel.getAll().size();
// Make OrderFile
orderFileModel.createNewFileObject();
orderFileModel.setFileName("Index");
orderFileModel.setFileType("html");
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader( (User) newSession.createCriteria(User.class).list().get(0) );
orderFileModel.setParent( (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0) );
newSession.save(orderFileModel.getOrderFile());
transactionBeginCommit();
int sizeWithNewRow = orderFileModel.getAll().size();
assertEquals(sizeBefore + 1, sizeWithNewRow);
// Clean data
OrderFile orderFile = (OrderFile) newSession.createCriteria(OrderFile.class).list().get(0);
newSession.delete(orderFile);
transactionBeginCommit();
newSession.close();
}
@Test
public void testDelete(){
newSession = sessionFactory.openSession();
int sizeBefore = orderFileModel.getAll().size();
// Make OrderFile
orderFileModel.createNewFileObject();
orderFileModel.setFileName("Main");
orderFileModel.setFileType("java");
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader( (User) newSession.createCriteria(User.class).list().get(0) );
orderFileModel.setParent( (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0) );
newSession.save(orderFileModel.getOrderFile());
transactionBeginCommit();
newSession.delete(orderFileModel.getOrderFile());
transactionBeginCommit();
int sizeAfter = orderFileModel.getAll().size();
assertEquals(sizeBefore, sizeAfter);
newSession.close();
}
@Test(expected = PropertyValueException.class)
public void testCreateNotValidRow(){
newSession = sessionFactory.openSession();
// Make OrderFile
orderFileModel.createNewFileObject();
orderFileModel.setFileName(null);
orderFileModel.setFileType("html");
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader( (User) newSession.createCriteria(User.class).list().get(0) );
orderFileModel.setParent( (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0) );
newSession.save(orderFileModel.getOrderFile());
transactionBeginCommit();
newSession.close();
}
@Test
public void testUpdate(){
newSession = sessionFactory.openSession();
// Make OrderFile
orderFileModel.createNewFileObject();
orderFileModel.setFileName("yii");
orderFileModel.setFileType("bat");
orderFileModel.setUploadDate(new Date());
orderFileModel.setUploader( (User) newSession.createCriteria(User.class).list().get(0) );
orderFileModel.setParent( (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0) );
newSession.save(orderFileModel.getOrderFile());
transactionBeginCommit();
// Get saved OrderFile and update it
OrderFile orderFile = (OrderFile) newSession.createCriteria(OrderFile.class).list().get(0);
orderFile.setName("yii2");
newSession.save(orderFile);
transactionBeginCommit();
// Get updated OrderFile and check for equality
OrderFile newOrderFile = (OrderFile) newSession.createCriteria(OrderFile.class).list().get(0);
assertTrue( newOrderFile.getName().equals("yii2") );
/**
* It is necessary to delete user and order element because it make influence on some other tests
*/
OrderFile orderFileToDelete = (OrderFile) newSession.createCriteria(OrderFile.class).list().get(0);
User userToDelete = (User) newSession.createCriteria(User.class).list().get(0);
OrderElement orderElementToDelete = (OrderElement) newSession.createCriteria(OrderElement.class).list().get(0);
newSession.delete(orderFileToDelete);
newSession.delete(userToDelete);
newSession.delete(orderElementToDelete);
transactionBeginCommit();
newSession.close();
}
public void initialize(){
newSession = sessionFactory.openSession();
createUser();
createOrderElement();
}
private void createUser(){
User user = User.create("harry-potter", "somePassword", "harry-potter@hogwarts.uk");
newSession.save(user);
transactionBeginCommit();
}
private void createOrderElement(){
OrderLine result = OrderLine.create();
result.setName("OrderLineB");
result.setCode("1a1k1k1k");
HoursGroup hoursGroup = HoursGroup.create(result);
hoursGroup.setWorkingHours(0);
hoursGroup.setCode("hoursGroupName1");
result.addHoursGroup(hoursGroup);
OrderElement orderElement = result;
orderElementModel.setCurrent(orderElement, new OrderModel());
newSession.save(orderElement);
transactionBeginCommit();
}
private void transactionBeginCommit(){
transaction = newSession.beginTransaction();
transaction.commit();
}
}

29
pom.xml
View file

@ -159,6 +159,7 @@
<id>gettext-commons-site</id>
<url>http://gettext-commons.googlecode.com/svn/maven-repository</url>
</repository>
<!-- LibrePlan repository -->
<repository>
<id>thirdparty</id>
@ -184,6 +185,7 @@
<!-- Dependency management -->
<dependencyManagement>
<dependencies>
<!-- Jasper Reports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
@ -195,24 +197,28 @@
<artifactId>jasperreports-fonts</artifactId>
<version>4.0.0</version>
</dependency>
<!-- GPL Jasperreport Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jasperreportcomponent</artifactId>
<version>1.0</version>
</dependency>
<!-- GPL JFreechartEngine for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jfreechartengine</artifactId>
<version>1.1</version>
</dependency>
<!-- GPL detailrow Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>customdetailrowcomponent</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Gettext commons -->
<dependency>
<groupId>org.xnap.commons</groupId>
@ -318,6 +324,7 @@
<artifactId>spring-security-acl</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<!-- Spring Dependency LDAP -->
<dependency>
<groupId>org.springframework.security</groupId>
@ -332,6 +339,7 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- datasource for testing -->
<dependency>
<groupId>com.jolbox</groupId>
@ -379,18 +387,21 @@
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<!-- Commons lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<!-- Commons Math-->
<dependency>
<groupId>commons-math</groupId>
<artifactId>commons-math</artifactId>
<version>1.2</version>
</dependency>
<!-- Commons Logging (required by many frameworks)-->
<dependency>
<groupId>commons-logging</groupId>
@ -407,6 +418,7 @@
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<!-- BeanShell (required by ZK)-->
<dependency>
<groupId>org.beanshell</groupId>
@ -414,6 +426,7 @@
<version>2.0b4</version>
<scope>runtime</scope>
</dependency>
<!-- Apache Commons Fileupload (required by ZK) -->
<dependency>
<groupId>commons-fileupload</groupId>
@ -421,6 +434,7 @@
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
<!-- ZK -->
<dependency>
<groupId>org.zkoss.zk</groupId>
@ -443,12 +457,14 @@
</exclusion>
</exclusions>
</dependency>
<!-- JGraphT -->
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-jdk1.5</artifactId>
<version>0.7.3</version>
</dependency>
<!-- Jfreechart -->
<dependency>
<groupId>jfree</groupId>
@ -460,18 +476,21 @@
<artifactId>jcommon</artifactId>
<version>1.0.16</version>
</dependency>
<!-- Joda Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
<!-- LibrePlan ZK Components -->
<dependency>
<groupId>org.libreplan</groupId>
<artifactId>ganttzk</artifactId>
<version>${project.version}</version>
</dependency>
<!-- LibrePlan Business -->
<dependency>
<groupId>org.libreplan</groupId>
@ -490,12 +509,14 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- JAX-RS API -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.0</version>
</dependency>
<!-- CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
@ -539,6 +560,7 @@
</exclusion>
</exclusions>
</dependency>
<!-- jackson provider -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
@ -550,6 +572,7 @@
<artifactId>jackson-xc</artifactId>
<version>1.9.9</version>
</dependency>
<!-- ZK Timeplot -->
<dependency>
<groupId>org.zkoss.zkforge</groupId>
@ -579,24 +602,28 @@
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.5</version>
</dependency>
<!-- jqPlot -->
<dependency>
<groupId>br.com.digilabs.jqplot</groupId>
<artifactId>jqplot4java</artifactId>
<version>1.2.3-javascript</version>
</dependency>
<!-- MPXJ Library -->
<dependency>
<groupId>net.sourceforge</groupId>
<artifactId>mpxj</artifactId>
<version>4.3.0</version>
</dependency>
<!-- ZK fileupload -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<!-- Quartz framework -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
@ -811,12 +838,14 @@
<artifactId>${jdbcDriver.artifactId}</artifactId>
<version>${jdbcDriver.version}</version>
</dependency>
<!-- connection pooling -->
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.7.1.RELEASE</version>
</dependency>
<!-- connection pooling dependencies -->
<dependency>
<groupId>org.slf4j</groupId>