Merge branch 'libreplan-1.3' into adapt-planning-according-timesheets
This commit is contained in:
commit
d258b989f9
63 changed files with 1349 additions and 182 deletions
23
HACKING
23
HACKING
|
|
@ -87,12 +87,21 @@ Fedora
|
||||||
|
|
||||||
* Install requirements::
|
* Install requirements::
|
||||||
|
|
||||||
# yum install git maven java-1.6.0-openjdk postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
|
# yum install git maven java-1.7.0-openjdk-devel postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
|
||||||
|
|
||||||
|
.. WARNING:: Use the following command in Fedora 16 or below::
|
||||||
|
|
||||||
|
# yum install git maven java-1.6.0-openjdk postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
|
||||||
|
|
||||||
* Start database service::
|
* Start database service::
|
||||||
|
|
||||||
# service postgresql initdb
|
# su - postgres -c "PGDATA=/var/lib/pgsql/data initdb"
|
||||||
# service postgresql start
|
# systemctl start postgresql.service
|
||||||
|
|
||||||
|
.. WARNING:: Use the following commands in Fedora 16 or below::
|
||||||
|
|
||||||
|
# service postgresql initdb
|
||||||
|
# service postgresql start
|
||||||
|
|
||||||
* Connect to database::
|
* Connect to database::
|
||||||
|
|
||||||
|
|
@ -110,11 +119,13 @@ Fedora
|
||||||
|
|
||||||
ALTER USER postgres WITH PASSWORD 'postgres';
|
ALTER USER postgres WITH PASSWORD 'postgres';
|
||||||
|
|
||||||
* Edit ``/var/lib/pgsql/data/pg_hba.conf`` and replace ``ident`` by ``md5``
|
.. WARNING:: These steps are only for Fedora 16 and below:
|
||||||
|
|
||||||
* Reload database configuration::
|
* Edit ``/var/lib/pgsql/data/pg_hba.conf`` and replace ``ident`` by ``md5``
|
||||||
|
|
||||||
# service postgresql reload
|
* Reload database configuration::
|
||||||
|
|
||||||
|
# service postgresql reload
|
||||||
|
|
||||||
* Download source code::
|
* Download source code::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -563,4 +563,11 @@ public abstract class Task implements ITaskFundamentalProperties {
|
||||||
return fundamentalProperties.getLastTimesheetDate();
|
return fundamentalProperties.getLastTimesheetDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void firePropertyChangeForTaskDates() {
|
||||||
|
fundamentalPropertiesListeners.firePropertyChange("beginDate", null,
|
||||||
|
getBeginDate());
|
||||||
|
fundamentalPropertiesListeners.firePropertyChange("endDate", null,
|
||||||
|
getEndDate());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ public abstract class BaseEntity implements INewObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static <T extends BaseEntity> T create(T baseEntity) {
|
protected static <T extends BaseEntity> T create(T baseEntity) {
|
||||||
baseEntity.newObject = true;
|
baseEntity.setNewObject(true);
|
||||||
return baseEntity;
|
return baseEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ public abstract class IntegrationEntity extends BaseEntity {
|
||||||
T integrationEntity, String code) {
|
T integrationEntity, String code) {
|
||||||
|
|
||||||
BaseEntity.create(integrationEntity);
|
BaseEntity.create(integrationEntity);
|
||||||
integrationEntity.code = code;
|
integrationEntity.setCode(code);
|
||||||
|
|
||||||
return integrationEntity;
|
return integrationEntity;
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ public abstract class IntegrationEntity extends BaseEntity {
|
||||||
T integrationEntity) {
|
T integrationEntity) {
|
||||||
|
|
||||||
BaseEntity.create(integrationEntity);
|
BaseEntity.create(integrationEntity);
|
||||||
integrationEntity.code = generateCode();
|
integrationEntity.setCode(generateCode());
|
||||||
|
|
||||||
return integrationEntity;
|
return integrationEntity;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,8 @@ public interface IOrderElementDAO extends IIntegrationEntityDAO<OrderElement> {
|
||||||
|
|
||||||
EffortDuration calculateMinWorkedHours(final List<OrderElement> list);
|
EffortDuration calculateMinWorkedHours(final List<OrderElement> list);
|
||||||
|
|
||||||
|
boolean isAlreadyInUse(OrderElement orderElement);
|
||||||
|
|
||||||
boolean isAlreadyInUseThisOrAnyOfItsChildren(OrderElement orderElement);
|
boolean isAlreadyInUseThisOrAnyOfItsChildren(OrderElement orderElement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,6 +132,8 @@ public interface IOrderElementDAO extends IIntegrationEntityDAO<OrderElement> {
|
||||||
|
|
||||||
boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException;
|
boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException;
|
||||||
|
|
||||||
|
boolean hasImputedExpenseSheetThisOrAnyOfItsChildren(Long id) throws InstanceNotFoundException;
|
||||||
|
|
||||||
OrderElement findByExternalCode(String code) throws InstanceNotFoundException;
|
OrderElement findByExternalCode(String code) throws InstanceNotFoundException;
|
||||||
|
|
||||||
public List<OrderElement> findByLabelsAndCriteria(Set<Label> labels,
|
public List<OrderElement> findByLabelsAndCriteria(Set<Label> labels,
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,8 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAlreadyInUse(OrderElement orderElement) {
|
@Override
|
||||||
|
public boolean isAlreadyInUse(OrderElement orderElement) {
|
||||||
if (orderElement.isNewObject()) {
|
if (orderElement.isNewObject()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -518,7 +519,14 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException {
|
public boolean hasImputedExpenseSheet(Long id)
|
||||||
|
throws InstanceNotFoundException {
|
||||||
|
OrderElement orderElement = find(id);
|
||||||
|
return (!expenseSheetLineDAO.findByOrderElement(orderElement).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasImputedExpenseSheetThisOrAnyOfItsChildren(Long id) throws InstanceNotFoundException {
|
||||||
OrderElement orderElement = find(id);
|
OrderElement orderElement = find(id);
|
||||||
return (!expenseSheetLineDAO.findByOrderElementAndChildren(orderElement).isEmpty());
|
return (!expenseSheetLineDAO.findByOrderElementAndChildren(orderElement).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import org.hibernate.validator.Valid;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.libreplan.business.advance.bootstrap.PredefinedAdvancedTypes;
|
import org.libreplan.business.advance.bootstrap.PredefinedAdvancedTypes;
|
||||||
import org.libreplan.business.advance.entities.AdvanceAssignment;
|
import org.libreplan.business.advance.entities.AdvanceAssignment;
|
||||||
|
import org.libreplan.business.advance.entities.AdvanceMeasurement;
|
||||||
import org.libreplan.business.advance.entities.AdvanceType;
|
import org.libreplan.business.advance.entities.AdvanceType;
|
||||||
import org.libreplan.business.advance.entities.DirectAdvanceAssignment;
|
import org.libreplan.business.advance.entities.DirectAdvanceAssignment;
|
||||||
import org.libreplan.business.advance.entities.IndirectAdvanceAssignment;
|
import org.libreplan.business.advance.entities.IndirectAdvanceAssignment;
|
||||||
|
|
@ -70,6 +71,7 @@ import org.libreplan.business.scenarios.entities.Scenario;
|
||||||
import org.libreplan.business.templates.entities.OrderElementTemplate;
|
import org.libreplan.business.templates.entities.OrderElementTemplate;
|
||||||
import org.libreplan.business.trees.ITreeNode;
|
import org.libreplan.business.trees.ITreeNode;
|
||||||
import org.libreplan.business.util.deepcopy.DeepCopy;
|
import org.libreplan.business.util.deepcopy.DeepCopy;
|
||||||
|
import org.libreplan.business.workingday.EffortDuration;
|
||||||
import org.libreplan.business.workingday.IntraDayDate;
|
import org.libreplan.business.workingday.IntraDayDate;
|
||||||
import org.libreplan.business.workreports.daos.IWorkReportLineDAO;
|
import org.libreplan.business.workreports.daos.IWorkReportLineDAO;
|
||||||
import org.libreplan.business.workreports.entities.WorkReportLine;
|
import org.libreplan.business.workreports.entities.WorkReportLine;
|
||||||
|
|
@ -1630,4 +1632,23 @@ public abstract class OrderElement extends IntegrationEntity implements
|
||||||
return sumChargedEffort.getLastTimesheetDate();
|
return sumChargedEffort.getLastTimesheetDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void detachFromParent() {
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdvanceMeasurement getLastAdvanceMeasurement() {
|
||||||
|
DirectAdvanceAssignment advanceAssignment = getReportGlobalAdvanceAssignment();
|
||||||
|
if (advanceAssignment == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return advanceAssignment.getLastAdvanceMeasurement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEffortAsString() {
|
||||||
|
SumChargedEffort sumChargedEffort = getSumChargedEffort();
|
||||||
|
EffortDuration effort = sumChargedEffort != null ? sumChargedEffort
|
||||||
|
.getTotalChargedEffort() : EffortDuration.zero();
|
||||||
|
return effort.toFormattedString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
|
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
|
||||||
* Desenvolvemento Tecnolóxico de Galicia
|
* Desenvolvemento Tecnolóxico de Galicia
|
||||||
* Copyright (C) 2010-2011 Igalia, S.L.
|
* Copyright (C) 2010-2012 Igalia, S.L.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
|
@ -26,13 +26,19 @@ import static org.libreplan.business.i18n.I18nHelper._;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Susana Montes Pedreiera <smotnes@wirelessgalicia.com>
|
* @author Susana Montes Pedreiera <smotnes@wirelessgalicia.com>
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public enum OrderStatusEnum {
|
public enum OrderStatusEnum {
|
||||||
|
|
||||||
OFFERED(_("OFFERED")), ACCEPTED(_("ACCEPTED")), STARTED(_("STARTED")), FINISHED(
|
PRE_SALES(_("PRE-SALES")),
|
||||||
_("FINISHED")), CANCELLED(_("CANCELLED")), SUBCONTRACTED_PENDING_ORDER(
|
OFFERED(_("OFFERED")),
|
||||||
_("SUBCONTRACTED PENDING PROJECT")), STORED(_("STORED"));
|
OUTSOURCED(_("OUTSOURCED")),
|
||||||
|
ACCEPTED(_("ACCEPTED")),
|
||||||
|
STARTED(_("STARTED")),
|
||||||
|
ON_HOLD(_("ON HOLD")),
|
||||||
|
FINISHED(_("FINISHED")),
|
||||||
|
CANCELLED(_("CANCELLED")),
|
||||||
|
STORED(_("STORED"));
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
|
@ -45,6 +51,6 @@ public enum OrderStatusEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OrderStatusEnum getDefault() {
|
public static OrderStatusEnum getDefault() {
|
||||||
return OFFERED;
|
return PRE_SALES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ public abstract class TaskElement extends BaseEntity {
|
||||||
|
|
||||||
protected static <T extends TaskElement> T create(T taskElement,
|
protected static <T extends TaskElement> T create(T taskElement,
|
||||||
TaskSource taskSource) {
|
TaskSource taskSource) {
|
||||||
taskElement.taskSource = taskSource;
|
taskElement.setTaskSource(taskSource);
|
||||||
taskElement.updateDeadlineFromOrderElement();
|
taskElement.updateDeadlineFromOrderElement();
|
||||||
taskElement.setName(taskElement.getOrderElement().getName());
|
taskElement.setName(taskElement.getOrderElement().getName());
|
||||||
taskElement.updateAdvancePercentageFromOrderElement();
|
taskElement.updateAdvancePercentageFromOrderElement();
|
||||||
|
|
@ -221,6 +221,10 @@ public abstract class TaskElement extends BaseEntity {
|
||||||
return taskSource;
|
return taskSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setTaskSource(TaskSource taskSource) {
|
||||||
|
this.taskSource = taskSource;
|
||||||
|
}
|
||||||
|
|
||||||
protected void copyDependenciesTo(TaskElement result) {
|
protected void copyDependenciesTo(TaskElement result) {
|
||||||
for (Dependency dependency : getDependenciesWithThisOrigin()) {
|
for (Dependency dependency : getDependenciesWithThisOrigin()) {
|
||||||
Dependency.create(result, dependency.getDestination(),
|
Dependency.create(result, dependency.getDestination(),
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public abstract class AllocationModification {
|
||||||
.unmodifiableList(new ArrayList<Resource>(resources));
|
.unmodifiableList(new ArrayList<Resource>(resources));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNoResources() {
|
protected boolean hasNoResources() {
|
||||||
return resourcesOnWhichApplyAllocation.isEmpty();
|
return resourcesOnWhichApplyAllocation.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> {
|
||||||
List<Worker> findByFirstNameSecondNameAndNifAnotherTransaction(
|
List<Worker> findByFirstNameSecondNameAndNifAnotherTransaction(
|
||||||
String firstname, String surname, String nif);
|
String firstname, String surname, String nif);
|
||||||
|
|
||||||
List<Object[]> getWorkingHoursGroupedPerWorker(List<String> workerNifs,
|
List<Object[]> getWorkingHoursGroupedPerWorker(List<String> workerCodes,
|
||||||
Date startingDate, Date endingDate);
|
Date startingDate, Date endingDate);
|
||||||
|
|
||||||
Worker findByNifAnotherTransaction(String nif)
|
Worker findByNifAnotherTransaction(String nif)
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,8 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<Object[]> getWorkingHoursGroupedPerWorker(
|
public List<Object[]> getWorkingHoursGroupedPerWorker(
|
||||||
List<String> workerNifs, Date startingDate, Date endingDate) {
|
List<String> workerCodes, Date startingDate, Date endingDate) {
|
||||||
String strQuery = "SELECT worker.nif, SUM(wrl.effort) "
|
String strQuery = "SELECT worker.code, SUM(wrl.effort) "
|
||||||
+ "FROM Worker worker, WorkReportLine wrl "
|
+ "FROM Worker worker, WorkReportLine wrl "
|
||||||
+ "LEFT OUTER JOIN wrl.resource resource "
|
+ "LEFT OUTER JOIN wrl.resource resource "
|
||||||
+ "WHERE resource.id = worker.id ";
|
+ "WHERE resource.id = worker.id ";
|
||||||
|
|
@ -165,15 +165,15 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set workers
|
// Set workers
|
||||||
if (workerNifs != null && !workerNifs.isEmpty()) {
|
if (workerCodes != null && !workerCodes.isEmpty()) {
|
||||||
strQuery += "AND worker.nif IN (:workerNifs) ";
|
strQuery += "AND worker.code IN (:workerCodes) ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group by
|
// Group by
|
||||||
strQuery += "GROUP BY worker.nif ";
|
strQuery += "GROUP BY worker.code ";
|
||||||
|
|
||||||
// Order by
|
// Order by
|
||||||
strQuery += "ORDER BY worker.nif";
|
strQuery += "ORDER BY worker.code";
|
||||||
|
|
||||||
// Set parameters
|
// Set parameters
|
||||||
Query query = getSession().createQuery(strQuery);
|
Query query = getSession().createQuery(strQuery);
|
||||||
|
|
@ -183,8 +183,8 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
||||||
if (endingDate != null) {
|
if (endingDate != null) {
|
||||||
query.setParameter("endingDate", endingDate);
|
query.setParameter("endingDate", endingDate);
|
||||||
}
|
}
|
||||||
if (workerNifs != null && !workerNifs.isEmpty()) {
|
if (workerCodes != null && !workerCodes.isEmpty()) {
|
||||||
query.setParameterList("workerNifs", workerNifs);
|
query.setParameterList("workerCodes", workerCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get result
|
// Get result
|
||||||
|
|
|
||||||
|
|
@ -107,18 +107,18 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
.getInitDate());
|
.getInitDate());
|
||||||
Days fromBeginningToEnd = daysBetween(order.getInitDate(), origin
|
Days fromBeginningToEnd = daysBetween(order.getInitDate(), origin
|
||||||
.getDeadline());
|
.getDeadline());
|
||||||
beingBuilt.materialAssignments = copyMaterialAssignmentsFrom(beingBuilt, origin
|
beingBuilt.setMaterialAssignments(copyMaterialAssignmentsFrom(beingBuilt, origin
|
||||||
.getMaterialAssignments());
|
.getMaterialAssignments()));
|
||||||
beingBuilt.criterionRequirements = copyDirectCriterionRequirements(
|
beingBuilt.setCriterionRequirements(copyDirectCriterionRequirements(
|
||||||
beingBuilt, origin.getDirectCriterionRequirement());
|
beingBuilt, origin.getDirectCriterionRequirement()));
|
||||||
beingBuilt.labels = new HashSet<Label>(origin.getLabels());
|
beingBuilt.addLabels(origin.getLabels());
|
||||||
beingBuilt.qualityForms = origin.getQualityForms();
|
beingBuilt.setQualityForms(origin.getQualityForms());
|
||||||
beingBuilt.advanceAssignmentTemplates = copyDirectAdvanceAssignments(
|
beingBuilt.setAdvanceAssignmentTemplates(copyDirectAdvanceAssignments(
|
||||||
beingBuilt, origin.getDirectAdvanceAssignments());
|
beingBuilt, origin.getDirectAdvanceAssignments()));
|
||||||
beingBuilt.infoComponent = infoComponentCopied;
|
beingBuilt.setInfoComponent(infoComponentCopied);
|
||||||
beingBuilt.schedulingStateType = origin.getSchedulingStateType();
|
beingBuilt.setSchedulingStateType(origin.getSchedulingStateType());
|
||||||
assignDates(beingBuilt, fromBeginningToStart, fromBeginningToEnd);
|
assignDates(beingBuilt, fromBeginningToStart, fromBeginningToEnd);
|
||||||
beingBuilt.origin = origin;
|
beingBuilt.setOrigin(origin);
|
||||||
return create(beingBuilt);
|
return create(beingBuilt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends OrderElementTemplate> T createNew(T beingBuilt) {
|
public static <T extends OrderElementTemplate> T createNew(T beingBuilt) {
|
||||||
beingBuilt.infoComponent = new InfoComponent();
|
beingBuilt.setInfoComponent(new InfoComponent());
|
||||||
assignDates(beingBuilt, null, null);
|
assignDates(beingBuilt, null, null);
|
||||||
return create(beingBuilt);
|
return create(beingBuilt);
|
||||||
}
|
}
|
||||||
|
|
@ -314,6 +314,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
return schedulingStateType;
|
return schedulingStateType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setSchedulingStateType(SchedulingState.Type schedulingStateType) {
|
||||||
|
this.schedulingStateType = schedulingStateType;
|
||||||
|
}
|
||||||
|
|
||||||
public OrderLineGroupTemplate getParent() {
|
public OrderLineGroupTemplate getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
@ -322,13 +326,17 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InfoComponent getInfoComponent() {
|
protected InfoComponent getInfoComponent() {
|
||||||
if (infoComponent == null) {
|
if (infoComponent == null) {
|
||||||
infoComponent = new InfoComponent();
|
infoComponent = new InfoComponent();
|
||||||
}
|
}
|
||||||
return infoComponent;
|
return infoComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setInfoComponent(InfoComponent infoComponent) {
|
||||||
|
this.infoComponent = infoComponent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a description of the type or template this object is
|
* @return a description of the type or template this object is
|
||||||
*/
|
*/
|
||||||
|
|
@ -388,6 +396,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
return Collections.unmodifiableSet(materialAssignments);
|
return Collections.unmodifiableSet(materialAssignments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setMaterialAssignments(Set<MaterialAssignmentTemplate> materialAssigments) {
|
||||||
|
this.materialAssignments = materialAssignments;
|
||||||
|
}
|
||||||
|
|
||||||
public void addMaterialAssignment(
|
public void addMaterialAssignment(
|
||||||
MaterialAssignmentTemplate materialAssignment) {
|
MaterialAssignmentTemplate materialAssignment) {
|
||||||
Validate.notNull(materialAssignment);
|
Validate.notNull(materialAssignment);
|
||||||
|
|
@ -429,6 +441,11 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
this.labels.add(label);
|
this.labels.add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addLabels(Collection<Label> labels){
|
||||||
|
Validate.notNull(labels);
|
||||||
|
this.labels.addAll(labels);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeLabel(Label label) {
|
public void removeLabel(Label label) {
|
||||||
this.labels.remove(label);
|
this.labels.remove(label);
|
||||||
}
|
}
|
||||||
|
|
@ -437,6 +454,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
return Collections.unmodifiableSet(qualityForms);
|
return Collections.unmodifiableSet(qualityForms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setQualityForms(Set<QualityForm> qualityForms) {
|
||||||
|
this.qualityForms = qualityForms;
|
||||||
|
}
|
||||||
|
|
||||||
public void addQualityForm(QualityForm qualityForm) {
|
public void addQualityForm(QualityForm qualityForm) {
|
||||||
qualityForms.add(qualityForm);
|
qualityForms.add(qualityForm);
|
||||||
}
|
}
|
||||||
|
|
@ -450,6 +471,11 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
return Collections.unmodifiableSet(advanceAssignmentTemplates);
|
return Collections.unmodifiableSet(advanceAssignmentTemplates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setAdvanceAssignmentTemplates(
|
||||||
|
Set<AdvanceAssignmentTemplate> advanceAssignmentTemplates) {
|
||||||
|
this.advanceAssignmentTemplates = advanceAssignmentTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRoot() {
|
public boolean isRoot() {
|
||||||
return getParent() == null;
|
return getParent() == null;
|
||||||
}
|
}
|
||||||
|
|
@ -497,6 +523,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
||||||
return Collections.unmodifiableSet(criterionRequirements);
|
return Collections.unmodifiableSet(criterionRequirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setCriterionRequirements(Set<CriterionRequirement> criterionRequirements) {
|
||||||
|
this.criterionRequirements = criterionRequirements;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract List<HoursGroup> getHoursGroups();
|
public abstract List<HoursGroup> getHoursGroups();
|
||||||
|
|
||||||
public abstract Integer getWorkHours();
|
public abstract Integer getWorkHours();
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
||||||
OrderElementTemplate.create(beingBuilt, group);
|
OrderElementTemplate.create(beingBuilt, group);
|
||||||
List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt,
|
List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt,
|
||||||
group.getChildren());
|
group.getChildren());
|
||||||
beingBuilt.children = result;
|
beingBuilt.setChildren(result);
|
||||||
beingBuilt.propagateIndirectCriterionRequirements();
|
beingBuilt.propagateIndirectCriterionRequirements();
|
||||||
return beingBuilt;
|
return beingBuilt;
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
||||||
* and it's needed to propagate its criteria while preserving the original
|
* and it's needed to propagate its criteria while preserving the original
|
||||||
* value of 'valid' field in {@link IndirectCriterionRequirement}
|
* value of 'valid' field in {@link IndirectCriterionRequirement}
|
||||||
*/
|
*/
|
||||||
private void propagateIndirectCriterionRequirements() {
|
protected void propagateIndirectCriterionRequirements() {
|
||||||
propagateIndirectCriterionRequirementsForOrderLineGroup(this);
|
propagateIndirectCriterionRequirementsForOrderLineGroup(this);
|
||||||
propagateIndirectCriterionRequirementsForOrderLines(this);
|
propagateIndirectCriterionRequirementsForOrderLines(this);
|
||||||
}
|
}
|
||||||
|
|
@ -217,6 +217,10 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
||||||
return Collections.unmodifiableList(children);
|
return Collections.unmodifiableList(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setChildren(List<OrderElementTemplate> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITreeParentNode<OrderElementTemplate> toContainer() {
|
public ITreeParentNode<OrderElementTemplate> toContainer() {
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -59,4 +59,7 @@ public interface IWorkReportDAO extends IIntegrationEntityDAO<WorkReport> {
|
||||||
|
|
||||||
boolean isAnyPersonalTimesheetAlreadySaved();
|
boolean isAnyPersonalTimesheetAlreadySaved();
|
||||||
|
|
||||||
|
List<WorkReport> findPersonalTimesheetsByResourceAndOrderElement(
|
||||||
|
Resource resource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,4 +74,7 @@ public interface IWorkReportLineDAO extends
|
||||||
|
|
||||||
Boolean isFinished(OrderElement orderElement);
|
Boolean isFinished(OrderElement orderElement);
|
||||||
|
|
||||||
|
List<WorkReportLine> findByOrderElementAndWorkReports(
|
||||||
|
OrderElement orderElement, List<WorkReport> workReports);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,19 +143,9 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public WorkReport getPersonalTimesheetWorkReport(Resource resource,
|
public WorkReport getPersonalTimesheetWorkReport(Resource resource,
|
||||||
LocalDate date, PersonalTimesheetsPeriodicityEnum periodicity) {
|
LocalDate date, PersonalTimesheetsPeriodicityEnum periodicity) {
|
||||||
WorkReportType workReportType;
|
|
||||||
try {
|
|
||||||
workReportType = workReportTypeDAO
|
|
||||||
.findUniqueByName(PredefinedWorkReportTypes.PERSONAL_TIMESHEETS
|
|
||||||
.getName());
|
|
||||||
} catch (NonUniqueResultException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (InstanceNotFoundException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
||||||
criteria.add(Restrictions.eq("workReportType", workReportType));
|
criteria.add(Restrictions.eq("workReportType",
|
||||||
|
getPersonalTimesheetsWorkReportType()));
|
||||||
List<WorkReport> personalTimesheets = criteria.add(
|
List<WorkReport> personalTimesheets = criteria.add(
|
||||||
Restrictions.eq("resource", resource)).list();
|
Restrictions.eq("resource", resource)).list();
|
||||||
|
|
||||||
|
|
@ -179,8 +169,7 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private WorkReportType getPersonalTimesheetsWorkReportType() {
|
||||||
public boolean isAnyPersonalTimesheetAlreadySaved() {
|
|
||||||
WorkReportType workReportType;
|
WorkReportType workReportType;
|
||||||
try {
|
try {
|
||||||
workReportType = workReportTypeDAO
|
workReportType = workReportTypeDAO
|
||||||
|
|
@ -191,10 +180,29 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
||||||
} catch (InstanceNotFoundException e) {
|
} catch (InstanceNotFoundException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
return workReportType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnyPersonalTimesheetAlreadySaved() {
|
||||||
|
WorkReportType workReportType = getPersonalTimesheetsWorkReportType();
|
||||||
|
|
||||||
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
||||||
criteria.add(Restrictions.eq("workReportType", workReportType));
|
criteria.add(Restrictions.eq("workReportType", workReportType));
|
||||||
return criteria.list().isEmpty();
|
return criteria.list().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<WorkReport> findPersonalTimesheetsByResourceAndOrderElement(
|
||||||
|
Resource resource) {
|
||||||
|
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
||||||
|
|
||||||
|
criteria.add(Restrictions.eq("workReportType",
|
||||||
|
getPersonalTimesheetsWorkReportType()));
|
||||||
|
criteria.add(Restrictions.eq("resource", resource));
|
||||||
|
|
||||||
|
return criteria.list();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,4 +199,16 @@ public class WorkReportLineDAO extends IntegrationEntityDAO<WorkReportLine>
|
||||||
return criteria.uniqueResult() != null;
|
return criteria.uniqueResult() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public List<WorkReportLine> findByOrderElementAndWorkReports(
|
||||||
|
OrderElement orderElement, List<WorkReport> workReports) {
|
||||||
|
Criteria criteria = getSession().createCriteria(WorkReportLine.class);
|
||||||
|
|
||||||
|
criteria.add(Restrictions.eq("orderElement", orderElement));
|
||||||
|
criteria.add(Restrictions.in("workReport", workReports));
|
||||||
|
|
||||||
|
return (List<WorkReportLine>) criteria.list();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,4 +155,36 @@
|
||||||
columnDataType="BOOLEAN" />
|
columnDataType="BOOLEAN" />
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="update-status-values-in-order_table" author="mrego">
|
||||||
|
<comment>Updating status values in order_table</comment>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="8" />
|
||||||
|
<where>state='6'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="7" />
|
||||||
|
<where>state='4'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="6" />
|
||||||
|
<where>state='3'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="4" />
|
||||||
|
<where>state='2'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="3" />
|
||||||
|
<where>state='1'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="2" />
|
||||||
|
<where>state='5'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="order_table">
|
||||||
|
<column name="state" value="1" />
|
||||||
|
<where>state='0'</where>
|
||||||
|
</update>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@
|
||||||
access="field"
|
access="field"
|
||||||
cascade="all"
|
cascade="all"
|
||||||
class="org.libreplan.business.orders.entities.OrderLineGroup"
|
class="org.libreplan.business.orders.entities.OrderLineGroup"
|
||||||
index="idx_order_element_on_parent"/>
|
index="idx_order_element_on_parent"
|
||||||
|
lazy="false" />
|
||||||
|
|
||||||
<many-to-one name="template"
|
<many-to-one name="template"
|
||||||
access="field"
|
access="field"
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,12 @@ public class ConcurrentModificationController extends GenericForwardComposer {
|
||||||
.info(
|
.info(
|
||||||
"an OptimistLockingFailureException caused a disruption to an user",
|
"an OptimistLockingFailureException caused a disruption to an user",
|
||||||
exception);
|
exception);
|
||||||
Executions.sendRedirect("/common/concurrent_modification.zul?back="
|
if (Executions.getCurrent() != null) {
|
||||||
+ backURL);
|
Executions.sendRedirect("/common/concurrent_modification.zul?back="
|
||||||
|
+ backURL);
|
||||||
|
} else {
|
||||||
|
LOG.warn("Impossible to do redirect due to OptimisticLockingFailureException because of Executions.getCurrent() is null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getBackURL() {
|
private static String getBackURL() {
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ public interface IOrderModel extends IIntegrationEntityModel {
|
||||||
|
|
||||||
PlanningState getPlanningState();
|
PlanningState getPlanningState();
|
||||||
|
|
||||||
boolean hasImputedExpenseSheets(OrderElement order);
|
boolean hasImputedExpenseSheetsThisOrAnyOfItsChildren(OrderElement order);
|
||||||
|
|
||||||
void removeAskedEndDate(EndDateCommunication endDate);
|
void removeAskedEndDate(EndDateCommunication endDate);
|
||||||
|
|
||||||
|
|
@ -145,4 +145,7 @@ public interface IOrderModel extends IIntegrationEntityModel {
|
||||||
|
|
||||||
boolean isAnyTaskWithConstraint(PositionConstraintType type);
|
boolean isAnyTaskWithConstraint(PositionConstraintType type);
|
||||||
|
|
||||||
|
boolean isOnlyChildAndParentAlreadyInUseByHoursOrExpenses(
|
||||||
|
OrderElement orderElement);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -843,7 +843,7 @@ public class OrderCRUDController extends GenericForwardComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void remove(Order order) {
|
private void remove(Order order) {
|
||||||
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheets(order);
|
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheetsThisOrAnyOfItsChildren(order);
|
||||||
if (hasImputedExpenseSheets) {
|
if (hasImputedExpenseSheets) {
|
||||||
messagesForUser
|
messagesForUser
|
||||||
.showMessage(
|
.showMessage(
|
||||||
|
|
|
||||||
|
|
@ -702,7 +702,8 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(OrderElement element) {
|
public void remove(OrderElement element) {
|
||||||
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheets(element);
|
boolean hasImputedExpenseSheets = orderModel
|
||||||
|
.hasImputedExpenseSheetsThisOrAnyOfItsChildren(element);
|
||||||
if (hasImputedExpenseSheets) {
|
if (hasImputedExpenseSheets) {
|
||||||
messagesForUser
|
messagesForUser
|
||||||
.showMessage(
|
.showMessage(
|
||||||
|
|
@ -719,10 +720,22 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
||||||
Level.ERROR,
|
Level.ERROR,
|
||||||
_("You cannot remove the task \"{0}\" because it has work reported on it or any of its children",
|
_("You cannot remove the task \"{0}\" because it has work reported on it or any of its children",
|
||||||
element.getName()));
|
element.getName()));
|
||||||
} else {
|
return;
|
||||||
super.remove(element);
|
|
||||||
getRenderer().removeCodeTextbox(element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean onlyChildAndParentAlreadyInUseByHoursOrExpenses = orderModel
|
||||||
|
.isOnlyChildAndParentAlreadyInUseByHoursOrExpenses(element);
|
||||||
|
if (onlyChildAndParentAlreadyInUseByHoursOrExpenses) {
|
||||||
|
messagesForUser
|
||||||
|
.showMessage(
|
||||||
|
Level.ERROR,
|
||||||
|
_("You cannot remove the task \"{0}\" because it is the only child of its parent and its parent has tracked time or imputed expenses",
|
||||||
|
element.getName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.remove(element);
|
||||||
|
getRenderer().removeCodeTextbox(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -869,12 +869,12 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public boolean hasImputedExpenseSheets(OrderElement order) {
|
public boolean hasImputedExpenseSheetsThisOrAnyOfItsChildren(OrderElement order) {
|
||||||
if (order.isNewObject()) {
|
if (order.isNewObject()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return orderElementDAO.hasImputedExpenseSheet(order.getId());
|
return orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(order.getId());
|
||||||
} catch (InstanceNotFoundException e) {
|
} catch (InstanceNotFoundException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -931,4 +931,24 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
||||||
return planningState.getRootTask().isAnyTaskWithConstraint(type);
|
return planningState.getRootTask().isAnyTaskWithConstraint(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public boolean isOnlyChildAndParentAlreadyInUseByHoursOrExpenses(
|
||||||
|
OrderElement orderElement) {
|
||||||
|
try {
|
||||||
|
OrderLineGroup parent = orderElement.getParent();
|
||||||
|
if (!parent.isOrder() && parent.getChildren().size() == 1) {
|
||||||
|
if (orderElementDAO.isAlreadyInUse(parent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1098,7 +1098,7 @@ _(
|
||||||
|
|
||||||
if (Arrays.asList(OrderStatusEnum.ACCEPTED,
|
if (Arrays.asList(OrderStatusEnum.ACCEPTED,
|
||||||
OrderStatusEnum.OFFERED, OrderStatusEnum.STARTED,
|
OrderStatusEnum.OFFERED, OrderStatusEnum.STARTED,
|
||||||
OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER).contains(
|
OrderStatusEnum.OUTSOURCED).contains(
|
||||||
state)) {
|
state)) {
|
||||||
if (taskElement.getAssignedStatus() == "assigned") {
|
if (taskElement.getAssignedStatus() == "assigned") {
|
||||||
cssClass = "order-open-assigned";
|
cssClass = "order-open-assigned";
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
|
||||||
private static final EnumSet<OrderStatusEnum> STATUS_VISUALIZED = EnumSet
|
private static final EnumSet<OrderStatusEnum> STATUS_VISUALIZED = EnumSet
|
||||||
.of(OrderStatusEnum.ACCEPTED, OrderStatusEnum.OFFERED,
|
.of(OrderStatusEnum.ACCEPTED, OrderStatusEnum.OFFERED,
|
||||||
OrderStatusEnum.STARTED,
|
OrderStatusEnum.STARTED,
|
||||||
OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER);
|
OrderStatusEnum.OUTSOURCED);
|
||||||
|
|
||||||
public void setPlanningControllerEntryPoints(
|
public void setPlanningControllerEntryPoints(
|
||||||
MultipleTabsPlannerController entryPoints) {
|
MultipleTabsPlannerController entryPoints) {
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,10 @@ public class PlanningStateCreator {
|
||||||
|
|
||||||
public PlanningState retrieveOrCreate(Desktop desktop, Order order,
|
public PlanningState retrieveOrCreate(Desktop desktop, Order order,
|
||||||
IActionsOnRetrieval onRetrieval) {
|
IActionsOnRetrieval onRetrieval) {
|
||||||
Object existent = desktop.getAttribute(ATTRIBUTE_NAME);
|
Object existent = null;
|
||||||
|
if (desktop != null) {
|
||||||
|
existent = desktop.getAttribute(ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
if (existent instanceof PlanningState) {
|
if (existent instanceof PlanningState) {
|
||||||
PlanningState result = (PlanningState) existent;
|
PlanningState result = (PlanningState) existent;
|
||||||
if (ObjectUtils.equals(order.getId(), result.getOrder().getId())) {
|
if (ObjectUtils.equals(order.getId(), result.getOrder().getId())) {
|
||||||
|
|
@ -230,7 +233,9 @@ public class PlanningStateCreator {
|
||||||
}
|
}
|
||||||
PlanningState result = createPlanning(reload(order));
|
PlanningState result = createPlanning(reload(order));
|
||||||
result.onRetrieval();
|
result.onRetrieval();
|
||||||
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
if (desktop != null) {
|
||||||
|
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,10 @@ public class EditTaskController extends GenericForwardComposer {
|
||||||
if (context.getRelativeTo() instanceof TaskComponent) {
|
if (context.getRelativeTo() instanceof TaskComponent) {
|
||||||
((TaskComponent) context.getRelativeTo()).updateProperties();
|
((TaskComponent) context.getRelativeTo()).updateProperties();
|
||||||
((TaskComponent) context.getRelativeTo()).invalidate();
|
((TaskComponent) context.getRelativeTo()).invalidate();
|
||||||
|
|
||||||
|
org.zkoss.ganttz.data.Task task = context.getMapper()
|
||||||
|
.findAssociatedBean(taskElement);
|
||||||
|
task.firePropertyChangeForTaskDates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,10 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
|
||||||
if (node.isLeaf() && !node.isEmptyLeaf()) {
|
if (node.isLeaf() && !node.isEmptyLeaf()) {
|
||||||
// Then a new container will be created
|
// Then a new container will be created
|
||||||
nameTextbox = getRenderer().getNameTextbox(node);
|
nameTextbox = getRenderer().getNameTextbox(node);
|
||||||
|
} else {
|
||||||
|
// select the parent row to add new children ASAP
|
||||||
|
tree.setSelectedItem(getRenderer().getTreeitemForNode(
|
||||||
|
newNode.getParent().getThis()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getModel().addElement(name.getValue(), hours.getValue());
|
getModel().addElement(name.getValue(), hours.getValue());
|
||||||
|
|
@ -1107,6 +1111,14 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Treeitem getTreeitemForNode(T node) {
|
||||||
|
Component cmp = hoursIntBoxByElement.get(node);
|
||||||
|
while (!(cmp instanceof Treeitem)) {
|
||||||
|
cmp = cmp.getParent();
|
||||||
|
}
|
||||||
|
return (Treeitem) cmp;
|
||||||
|
}
|
||||||
|
|
||||||
private Constraint getHoursConstraintFor(final T line) {
|
private Constraint getHoursConstraintFor(final T line) {
|
||||||
return new Constraint() {
|
return new Constraint() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,9 @@ import javax.annotation.Resource;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.libreplan.business.advance.entities.AdvanceMeasurement;
|
import org.libreplan.business.advance.entities.AdvanceMeasurement;
|
||||||
import org.libreplan.business.advance.entities.DirectAdvanceAssignment;
|
|
||||||
import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum;
|
import org.libreplan.business.common.entities.PersonalTimesheetsPeriodicityEnum;
|
||||||
import org.libreplan.business.orders.entities.OrderElement;
|
import org.libreplan.business.orders.entities.OrderElement;
|
||||||
import org.libreplan.business.orders.entities.SumChargedEffort;
|
|
||||||
import org.libreplan.business.planner.entities.Task;
|
import org.libreplan.business.planner.entities.Task;
|
||||||
import org.libreplan.business.workingday.EffortDuration;
|
|
||||||
import org.libreplan.web.common.Util;
|
import org.libreplan.web.common.Util;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
import org.zkoss.zk.ui.event.Event;
|
import org.zkoss.zk.ui.event.Event;
|
||||||
|
|
@ -75,21 +72,15 @@ public class MyTasksAreaController extends GenericForwardComposer {
|
||||||
|
|
||||||
Util.appendLabel(row, getProgress(orderElement));
|
Util.appendLabel(row, getProgress(orderElement));
|
||||||
|
|
||||||
Util.appendLabel(row, getEffort(orderElement));
|
Util.appendLabel(row, _("{0} h", orderElement.getEffortAsString()));
|
||||||
|
|
||||||
appendTimeTrackingButton(row, task);
|
appendTimeTrackingButton(row, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEffort(OrderElement orderElement) {
|
|
||||||
SumChargedEffort sumChargedEffort = orderElement.getSumChargedEffort();
|
|
||||||
EffortDuration effort = sumChargedEffort != null ? sumChargedEffort
|
|
||||||
.getTotalChargedEffort() : EffortDuration.zero();
|
|
||||||
return _("{0} h", effort.toFormattedString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getProgress(OrderElement orderElement) {
|
private String getProgress(OrderElement orderElement) {
|
||||||
|
|
||||||
AdvanceMeasurement lastAdvanceMeasurement = getLastAdvanceMeasurement(orderElement);
|
AdvanceMeasurement lastAdvanceMeasurement = orderElement
|
||||||
|
.getLastAdvanceMeasurement();
|
||||||
if (lastAdvanceMeasurement != null) {
|
if (lastAdvanceMeasurement != null) {
|
||||||
return MessageFormat.format("[{0} %] ({1})",
|
return MessageFormat.format("[{0} %] ({1})",
|
||||||
lastAdvanceMeasurement.getValue(),
|
lastAdvanceMeasurement.getValue(),
|
||||||
|
|
@ -98,17 +89,6 @@ public class MyTasksAreaController extends GenericForwardComposer {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private AdvanceMeasurement getLastAdvanceMeasurement(
|
|
||||||
OrderElement orderElement) {
|
|
||||||
DirectAdvanceAssignment advanceAssignment = orderElement
|
|
||||||
.getReportGlobalAdvanceAssignment();
|
|
||||||
if (advanceAssignment == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return advanceAssignment
|
|
||||||
.getLastAdvanceMeasurement();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendTimeTrackingButton(Row row, final Task task) {
|
private void appendTimeTrackingButton(Row row, final Task task) {
|
||||||
EventListener trackTimeButtonListener = new EventListener() {
|
EventListener trackTimeButtonListener = new EventListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.libreplan.business.resources.entities.Resource;
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
import org.libreplan.business.users.entities.User;
|
import org.libreplan.business.users.entities.User;
|
||||||
|
import org.libreplan.web.UserUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities class for user dashboard window
|
* Utilities class for user dashboard window
|
||||||
|
|
@ -38,4 +39,12 @@ public class UserDashboardUtil {
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Resource getBoundResourceFromSession() {
|
||||||
|
User user = UserUtil.getUserFromSession();
|
||||||
|
if (user.isBound()) {
|
||||||
|
return user.getWorker();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
|
||||||
|
* Desenvolvemento Tecnolóxico de Galicia
|
||||||
|
* Copyright (C) 2010-2011 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.api;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for managing operations related with bound users.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
public interface IBoundUserService {
|
||||||
|
|
||||||
|
TaskListDTO getTasks();
|
||||||
|
|
||||||
|
Response getTimesheetEntriesByTask(String taskCode);
|
||||||
|
|
||||||
|
Response importTimesheetEntries(PersonalTimesheetEntryListDTO dto);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.api;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for an entry in a personal timesheet.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "personal-timesheet-entry")
|
||||||
|
public class PersonalTimesheetEntryDTO {
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String task;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "date")
|
||||||
|
public XMLGregorianCalendar date;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String effort;
|
||||||
|
|
||||||
|
public PersonalTimesheetEntryDTO() {}
|
||||||
|
|
||||||
|
public PersonalTimesheetEntryDTO(String task, XMLGregorianCalendar date,
|
||||||
|
String effort) {
|
||||||
|
this.task = task;
|
||||||
|
this.date = date;
|
||||||
|
this.effort = effort;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.api;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for a list of personal timesheet entries.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "personal-timesheet-entry-list")
|
||||||
|
public class PersonalTimesheetEntryListDTO {
|
||||||
|
|
||||||
|
@XmlElement(name = "personal-timesheet-entry")
|
||||||
|
public List<PersonalTimesheetEntryDTO> entries = new ArrayList<PersonalTimesheetEntryDTO>();
|
||||||
|
|
||||||
|
public PersonalTimesheetEntryListDTO() {}
|
||||||
|
|
||||||
|
public PersonalTimesheetEntryListDTO(List<PersonalTimesheetEntryDTO> entries) {
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.api;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
|
||||||
|
import org.libreplan.business.planner.entities.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for a {@link Task} entity.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "task")
|
||||||
|
public class TaskDTO {
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String code;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "project-code")
|
||||||
|
public String projectCode;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "project-name")
|
||||||
|
public String projectName;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "start-date")
|
||||||
|
public XMLGregorianCalendar startDate;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "end-date")
|
||||||
|
public XMLGregorianCalendar endDate;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "progress-value")
|
||||||
|
public BigDecimal progressValue;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "progress-date")
|
||||||
|
public XMLGregorianCalendar progressDate;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String effort;
|
||||||
|
|
||||||
|
public TaskDTO() {}
|
||||||
|
|
||||||
|
public TaskDTO(String name, String code, String projectCode,
|
||||||
|
String projectName, XMLGregorianCalendar startDate,
|
||||||
|
XMLGregorianCalendar endDate, BigDecimal progressValue,
|
||||||
|
XMLGregorianCalendar progressDate, String effort) {
|
||||||
|
this.name = name;
|
||||||
|
this.code = code;
|
||||||
|
this.projectCode = projectCode;
|
||||||
|
this.projectName = projectName;
|
||||||
|
this.startDate = startDate;
|
||||||
|
this.endDate = endDate;
|
||||||
|
this.progressValue = progressValue;
|
||||||
|
this.progressDate = progressDate;
|
||||||
|
this.effort = effort;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.api;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import org.libreplan.business.planner.entities.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for a list of {@link Task} entities.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "task-list")
|
||||||
|
public class TaskListDTO {
|
||||||
|
|
||||||
|
@XmlElement(name = "task")
|
||||||
|
public List<TaskDTO> tasks = new ArrayList<TaskDTO>();
|
||||||
|
|
||||||
|
public TaskListDTO() {}
|
||||||
|
|
||||||
|
public TaskListDTO(List<TaskDTO> tasks) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specification of namespace for REST-based services.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, namespace = WSCommonGlobalNames.REST_NAMESPACE)
|
||||||
|
package org.libreplan.ws.boundusers.api;
|
||||||
|
|
||||||
|
import org.libreplan.ws.common.api.WSCommonGlobalNames;
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.impl;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||||
|
import org.libreplan.business.orders.daos.IOrderElementDAO;
|
||||||
|
import org.libreplan.business.orders.entities.OrderElement;
|
||||||
|
import org.libreplan.business.workingday.EffortDuration;
|
||||||
|
import org.libreplan.business.workreports.daos.IWorkReportDAO;
|
||||||
|
import org.libreplan.business.workreports.daos.IWorkReportLineDAO;
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReport;
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReportLine;
|
||||||
|
import org.libreplan.web.users.dashboard.IMyTasksAreaModel;
|
||||||
|
import org.libreplan.web.users.dashboard.IPersonalTimesheetModel;
|
||||||
|
import org.libreplan.web.users.dashboard.UserDashboardUtil;
|
||||||
|
import org.libreplan.ws.boundusers.api.IBoundUserService;
|
||||||
|
import org.libreplan.ws.boundusers.api.PersonalTimesheetEntryDTO;
|
||||||
|
import org.libreplan.ws.boundusers.api.PersonalTimesheetEntryListDTO;
|
||||||
|
import org.libreplan.ws.boundusers.api.TaskListDTO;
|
||||||
|
import org.libreplan.ws.common.impl.DateConverter;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST-based implementation of {@link IBoundUserService};
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@Path("/bounduser/")
|
||||||
|
@Produces("application/xml")
|
||||||
|
@Service("boundUserServiceREST")
|
||||||
|
public class BoundUserServiceREST implements IBoundUserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMyTasksAreaModel myTasksAreaModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderElementDAO orderElementDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkReportDAO workReportDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IWorkReportLineDAO workReportLineDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPersonalTimesheetModel personalTimesheetModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@GET
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@Path("/mytasks/")
|
||||||
|
public TaskListDTO getTasks() {
|
||||||
|
return TaskConverter.toDTO(myTasksAreaModel.getTasks());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@GET
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@Path("/timesheets/{task-code}/")
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Response getTimesheetEntriesByTask(
|
||||||
|
@PathParam("task-code") String taskCode) {
|
||||||
|
try {
|
||||||
|
OrderElement orderElement = orderElementDAO.findByCode(taskCode);
|
||||||
|
List<WorkReport> workReports = workReportDAO
|
||||||
|
.findPersonalTimesheetsByResourceAndOrderElement(UserDashboardUtil
|
||||||
|
.getBoundResourceFromSession());
|
||||||
|
List<WorkReportLine> workReportLines = workReportLineDAO
|
||||||
|
.findByOrderElementAndWorkReports(orderElement, workReports);
|
||||||
|
Collections.sort(workReportLines);
|
||||||
|
Collections.reverse(workReportLines);
|
||||||
|
PersonalTimesheetEntryListDTO dto = PersonalTimesheetEntryConverter
|
||||||
|
.toDTO(workReportLines);
|
||||||
|
return Response.ok(dto).build();
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
return Response.status(Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@POST
|
||||||
|
@Transactional
|
||||||
|
@Path("/timesheets/")
|
||||||
|
public Response importTimesheetEntries(PersonalTimesheetEntryListDTO dto) {
|
||||||
|
try {
|
||||||
|
for (PersonalTimesheetEntryDTO each : dto.entries) {
|
||||||
|
LocalDate date = DateConverter.toLocalDate(each.date);
|
||||||
|
OrderElement orderElement = orderElementDAO
|
||||||
|
.findByCode(each.task);
|
||||||
|
EffortDuration effortDuration = EffortDuration
|
||||||
|
.parseFromFormattedString(each.effort);
|
||||||
|
|
||||||
|
personalTimesheetModel.initCreateOrEdit(date);
|
||||||
|
personalTimesheetModel.setEffortDuration(orderElement, date,
|
||||||
|
effortDuration);
|
||||||
|
personalTimesheetModel.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.ok().build();
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
return Response.status(Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.libreplan.business.workreports.entities.WorkReportLine;
|
||||||
|
import org.libreplan.ws.boundusers.api.PersonalTimesheetEntryDTO;
|
||||||
|
import org.libreplan.ws.boundusers.api.PersonalTimesheetEntryListDTO;
|
||||||
|
import org.libreplan.ws.common.impl.DateConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter from/to {@link WorkReportLine} to/from DTOs.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
public final class PersonalTimesheetEntryConverter {
|
||||||
|
|
||||||
|
private PersonalTimesheetEntryConverter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static PersonalTimesheetEntryDTO toDTO(
|
||||||
|
WorkReportLine workReportLine) {
|
||||||
|
return new PersonalTimesheetEntryDTO(workReportLine.getOrderElement()
|
||||||
|
.getCode(), DateConverter.toXMLGregorianCalendar(workReportLine
|
||||||
|
.getDate()), workReportLine.getEffort().toFormattedString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static PersonalTimesheetEntryListDTO toDTO(
|
||||||
|
Collection<WorkReportLine> workReportLines) {
|
||||||
|
List<PersonalTimesheetEntryDTO> dtos = new ArrayList<PersonalTimesheetEntryDTO>();
|
||||||
|
for (WorkReportLine line : workReportLines) {
|
||||||
|
dtos.add(toDTO(line));
|
||||||
|
}
|
||||||
|
return new PersonalTimesheetEntryListDTO(dtos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.boundusers.impl;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.libreplan.business.advance.entities.AdvanceMeasurement;
|
||||||
|
import org.libreplan.business.orders.entities.OrderElement;
|
||||||
|
import org.libreplan.business.planner.entities.Task;
|
||||||
|
import org.libreplan.ws.boundusers.api.TaskDTO;
|
||||||
|
import org.libreplan.ws.boundusers.api.TaskListDTO;
|
||||||
|
import org.libreplan.ws.common.impl.DateConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter from/to {@link Task} related entities to/from DTOs.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
public final class TaskConverter {
|
||||||
|
|
||||||
|
private TaskConverter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static TaskDTO toDTO(Task task) {
|
||||||
|
OrderElement orderElement = task.getOrderElement();
|
||||||
|
|
||||||
|
AdvanceMeasurement lastAdvanceMeasurement = orderElement
|
||||||
|
.getLastAdvanceMeasurement();
|
||||||
|
BigDecimal progressValue = null;
|
||||||
|
LocalDate progressDate = null;
|
||||||
|
if (lastAdvanceMeasurement != null) {
|
||||||
|
progressValue = lastAdvanceMeasurement.getValue();
|
||||||
|
progressDate = lastAdvanceMeasurement.getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TaskDTO(task.getName(), orderElement.getCode(), orderElement
|
||||||
|
.getOrder().getCode(), orderElement.getOrder().getName(),
|
||||||
|
DateConverter.toXMLGregorianCalendar(task.getStartDate()),
|
||||||
|
DateConverter.toXMLGregorianCalendar(task.getEndDate()),
|
||||||
|
progressValue,
|
||||||
|
DateConverter.toXMLGregorianCalendar(progressDate),
|
||||||
|
orderElement.getEffortAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static TaskListDTO toDTO(Collection<Task> tasks) {
|
||||||
|
List<TaskDTO> dtos = new ArrayList<TaskDTO>();
|
||||||
|
for (Task each : tasks) {
|
||||||
|
dtos.add(toDTO(each));
|
||||||
|
}
|
||||||
|
return new TaskListDTO(dtos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.common.api;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for representing any concurrent modification exception in the web
|
||||||
|
* services.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "concurrent-modification-error")
|
||||||
|
public class ConcurrentModificationErrorDTO {
|
||||||
|
|
||||||
|
@XmlAttribute(name = "message")
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
@XmlElement(name = "stack-trace")
|
||||||
|
public String stackTrace;
|
||||||
|
|
||||||
|
public ConcurrentModificationErrorDTO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentModificationErrorDTO(String message, String stackTrace) {
|
||||||
|
this.message = message;
|
||||||
|
this.stackTrace = stackTrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.common.api;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for representing any basic error in the web services.
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "error")
|
||||||
|
public class ErrorDTO {
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
public ErrorDTO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorDTO(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* This file is part of LibrePlan
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* 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.ws.common.impl;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.ext.ExceptionMapper;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
import org.libreplan.ws.common.api.ConcurrentModificationErrorDTO;
|
||||||
|
import org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception mapper for {@link HibernateOptimisticLockingFailureExceptionMapper}
|
||||||
|
*
|
||||||
|
* @author Manuel Rego Casasnovas <rego@igalia.com>
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
@Component("hibernateOptimisticLockingFailureException")
|
||||||
|
public class HibernateOptimisticLockingFailureExceptionMapper implements
|
||||||
|
ExceptionMapper<HibernateOptimisticLockingFailureException> {
|
||||||
|
|
||||||
|
public Response toResponse(HibernateOptimisticLockingFailureException e) {
|
||||||
|
return Response
|
||||||
|
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||||
|
.entity(new ConcurrentModificationErrorDTO(
|
||||||
|
e.getMessage(), Util.getStackTrace(e)))
|
||||||
|
.type("application/xml").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -39,4 +39,6 @@ public interface IOrderElementService {
|
||||||
|
|
||||||
Response getOrderElement(String code);
|
Response getOrderElement(String code);
|
||||||
|
|
||||||
|
Response removeOrderElement(String code);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,28 @@
|
||||||
|
|
||||||
package org.libreplan.ws.orders.impl;
|
package org.libreplan.ws.orders.impl;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
import org.libreplan.business.common.daos.IIntegrationEntityDAO;
|
import org.libreplan.business.common.daos.IIntegrationEntityDAO;
|
||||||
|
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.orders.daos.IOrderDAO;
|
import org.libreplan.business.orders.daos.IOrderDAO;
|
||||||
|
import org.libreplan.business.orders.daos.IOrderElementDAO;
|
||||||
import org.libreplan.business.orders.entities.Order;
|
import org.libreplan.business.orders.entities.Order;
|
||||||
|
import org.libreplan.business.orders.entities.OrderElement;
|
||||||
|
import org.libreplan.business.orders.entities.OrderLineGroup;
|
||||||
|
import org.libreplan.web.orders.IOrderModel;
|
||||||
|
import org.libreplan.ws.common.api.ErrorDTO;
|
||||||
import org.libreplan.ws.common.api.InstanceConstraintViolationsListDTO;
|
import org.libreplan.ws.common.api.InstanceConstraintViolationsListDTO;
|
||||||
import org.libreplan.ws.common.api.OrderDTO;
|
import org.libreplan.ws.common.api.OrderDTO;
|
||||||
import org.libreplan.ws.common.impl.ConfigurationOrderElementConverter;
|
import org.libreplan.ws.common.impl.ConfigurationOrderElementConverter;
|
||||||
|
|
@ -60,6 +70,12 @@ public class OrderElementServiceREST extends
|
||||||
@Autowired
|
@Autowired
|
||||||
private IOrderDAO orderDAO;
|
private IOrderDAO orderDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderElementDAO orderElementDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderModel orderModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@GET
|
@GET
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
|
@ -108,4 +124,95 @@ public class OrderElementServiceREST extends
|
||||||
return getDTOByCode(code);
|
return getDTOByCode(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DELETE
|
||||||
|
@Path("/{code}/")
|
||||||
|
@Transactional
|
||||||
|
public Response removeOrderElement(@PathParam("code") String code) {
|
||||||
|
try {
|
||||||
|
OrderElement orderElement = orderElementDAO.findByCode(code);
|
||||||
|
String errorMessage = checkRemovalValidation(orderElement);
|
||||||
|
if (errorMessage != null) {
|
||||||
|
return Response.status(Status.FORBIDDEN)
|
||||||
|
.entity(new ErrorDTO(errorMessage)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderElement.isOrder()) {
|
||||||
|
orderModel.remove((Order) orderElement);
|
||||||
|
} else {
|
||||||
|
Order order = orderDAO.loadOrderAvoidingProxyFor(orderElement);
|
||||||
|
orderModel.initEdit(order, null);
|
||||||
|
order = orderModel.getOrder();
|
||||||
|
|
||||||
|
orderElement = findOrderElement(order, orderElement.getId());
|
||||||
|
|
||||||
|
OrderLineGroup parent = orderElement.getParent();
|
||||||
|
parent.remove(orderElement);
|
||||||
|
orderElement.detachFromParent();
|
||||||
|
|
||||||
|
if (!parent.isOrder() && parent.getChildren().isEmpty()) {
|
||||||
|
OrderElement newElement = parent.toLeaf();
|
||||||
|
if (!order.isCodeAutogenerated()) {
|
||||||
|
newElement.setCode(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
parent.getParent().replace(parent, newElement);
|
||||||
|
parent.detachFromParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
orderModel.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.ok().build();
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
return Response.status(Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String checkRemovalValidation(OrderElement orderElement) {
|
||||||
|
try {
|
||||||
|
if (orderElementDAO
|
||||||
|
.isAlreadyInUseThisOrAnyOfItsChildren(orderElement)) {
|
||||||
|
return "You cannot remove the order element '"
|
||||||
|
+ orderElement.getName()
|
||||||
|
+ "' because it or any of its children have tracked time in some work report";
|
||||||
|
}
|
||||||
|
if (orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(orderElement.getId())) {
|
||||||
|
return "You cannot remove the order element '"
|
||||||
|
+ orderElement.getName()
|
||||||
|
+ "' because it or any of its children have tracked expenses in some expenses sheet";
|
||||||
|
}
|
||||||
|
|
||||||
|
OrderLineGroup parent = orderElement.getParent();
|
||||||
|
if (!parent.isOrder() && parent.getChildren().size() == 1) {
|
||||||
|
if (orderElementDAO.isAlreadyInUse(parent)) {
|
||||||
|
return "You cannot remove the order element '"
|
||||||
|
+ orderElement.getName()
|
||||||
|
+ "' because it is the only child of its parent and its parent has tracked time in some work report";
|
||||||
|
}
|
||||||
|
if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) {
|
||||||
|
return "You cannot remove the order element '"
|
||||||
|
+ orderElement.getName()
|
||||||
|
+ "' because it is the only child of its parent and its parent has tracked expenses in some expenses sheet";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderElement findOrderElement(OrderElement orderElement, Long id) {
|
||||||
|
if (orderElement.getId().equals(id)) {
|
||||||
|
return orderElement;
|
||||||
|
}
|
||||||
|
for (OrderElement child : orderElement.getChildren()) {
|
||||||
|
OrderElement found = findOrderElement(child, id);
|
||||||
|
if (found != null) {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,13 +87,13 @@ public class ResourceHoursServiceREST implements IResourceHoursService {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> workerNifs = null;
|
List<String> workerCodes = null;
|
||||||
if (resourceCode != null) {
|
if (resourceCode != null) {
|
||||||
workerNifs = Arrays.asList(resourceCode);
|
workerCodes = Arrays.asList(resourceCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Object[]> hoursPerWorker = workerDAO
|
List<Object[]> hoursPerWorker = workerDAO
|
||||||
.getWorkingHoursGroupedPerWorker(workerNifs, startingDate,
|
.getWorkingHoursGroupedPerWorker(workerCodes, startingDate,
|
||||||
endingDate);
|
endingDate);
|
||||||
|
|
||||||
for (Object[] pair : hoursPerWorker) {
|
for (Object[] pair : hoursPerWorker) {
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ public class SubcontractServiceREST implements ISubcontractService {
|
||||||
order.setCode(code);
|
order.setCode(code);
|
||||||
generateCodes(order);
|
generateCodes(order);
|
||||||
|
|
||||||
order.setState(OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER);
|
order.setState(OrderStatusEnum.OUTSOURCED);
|
||||||
|
|
||||||
if (subcontractedTaskDataDTO.workDescription != null) {
|
if (subcontractedTaskDataDTO.workDescription != null) {
|
||||||
order.setName(subcontractedTaskDataDTO.workDescription);
|
order.setName(subcontractedTaskDataDTO.workDescription);
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,13 @@
|
||||||
<ref bean="materialServiceREST"/>
|
<ref bean="materialServiceREST"/>
|
||||||
<ref bean="unitTypeServiceREST"/>
|
<ref bean="unitTypeServiceREST"/>
|
||||||
<ref bean="expenseSheetServiceREST"/>
|
<ref bean="expenseSheetServiceREST"/>
|
||||||
|
<ref bean="boundUserServiceREST"/>
|
||||||
</jaxrs:serviceBeans>
|
</jaxrs:serviceBeans>
|
||||||
<jaxrs:providers>
|
<jaxrs:providers>
|
||||||
<ref bean="runtimeExceptionMapper" />
|
<ref bean="runtimeExceptionMapper" />
|
||||||
<ref bean="instanceNotFoundExceptionMapper" />
|
<ref bean="instanceNotFoundExceptionMapper" />
|
||||||
<ref bean="incompatibleTypeExceptionMapper" />
|
<ref bean="incompatibleTypeExceptionMapper" />
|
||||||
|
<ref bean="hibernateOptimisticLockingFailureException" />
|
||||||
</jaxrs:providers>
|
</jaxrs:providers>
|
||||||
<!-- FIXME: in root pom.xml, enable CXF logging on development and
|
<!-- FIXME: in root pom.xml, enable CXF logging on development and
|
||||||
disable it in production.
|
disable it in production.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@
|
||||||
entry-point-ref="customAuthenticationEntryPoint">
|
entry-point-ref="customAuthenticationEntryPoint">
|
||||||
|
|
||||||
<!-- Web services -->
|
<!-- Web services -->
|
||||||
|
<intercept-url pattern="/ws/rest/bounduser/**"
|
||||||
|
access="ROLE_BOUND_USER"
|
||||||
|
method="GET" />
|
||||||
|
<intercept-url pattern="/ws/rest/bounduser/**"
|
||||||
|
access="ROLE_BOUND_USER"
|
||||||
|
method="POST" />
|
||||||
<intercept-url pattern="/ws/rest/subcontracting/**"
|
<intercept-url pattern="/ws/rest/subcontracting/**"
|
||||||
access="ROLE_WS_SUBCONTRACTING"
|
access="ROLE_WS_SUBCONTRACTING"
|
||||||
method="GET" />
|
method="GET" />
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ import java.util.SortedSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
|
|
@ -536,6 +538,18 @@ public class OrderElementServiceTest {
|
||||||
public void validOrderWithOrderLineGroup() {
|
public void validOrderWithOrderLineGroup() {
|
||||||
String code = UUID.randomUUID().toString();
|
String code = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
OrderDTO orderDTO = createOrderDTOWithChildren(code);
|
||||||
|
|
||||||
|
OrderListDTO orderListDTO = createOrderListDTO(orderDTO);
|
||||||
|
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = orderElementService
|
||||||
|
.addOrders(orderListDTO).instanceConstraintViolationsList;
|
||||||
|
assertTrue(instanceConstraintViolationsList.toString(),
|
||||||
|
instanceConstraintViolationsList.size() == 0);
|
||||||
|
|
||||||
|
checkIfExistsByCodeInAnotherTransaction(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderDTO createOrderDTOWithChildren(String code) {
|
||||||
OrderDTO orderDTO = new OrderDTO();
|
OrderDTO orderDTO = new OrderDTO();
|
||||||
orderDTO.name = "Order name " + UUID.randomUUID().toString();
|
orderDTO.name = "Order name " + UUID.randomUUID().toString();
|
||||||
orderDTO.code = code;
|
orderDTO.code = code;
|
||||||
|
|
@ -557,6 +571,14 @@ public class OrderElementServiceTest {
|
||||||
orderLineGroupDTO.children.add(orderLineDTO);
|
orderLineGroupDTO.children.add(orderLineDTO);
|
||||||
|
|
||||||
orderDTO.children.add(orderLineGroupDTO);
|
orderDTO.children.add(orderLineGroupDTO);
|
||||||
|
return orderDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeOrderElement() {
|
||||||
|
final String code = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
final OrderDTO orderDTO = createOrderDTOWithChildren(code);
|
||||||
|
|
||||||
OrderListDTO orderListDTO = createOrderListDTO(orderDTO);
|
OrderListDTO orderListDTO = createOrderListDTO(orderDTO);
|
||||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = orderElementService
|
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = orderElementService
|
||||||
|
|
@ -565,6 +587,32 @@ public class OrderElementServiceTest {
|
||||||
instanceConstraintViolationsList.size() == 0);
|
instanceConstraintViolationsList.size() == 0);
|
||||||
|
|
||||||
checkIfExistsByCodeInAnotherTransaction(code);
|
checkIfExistsByCodeInAnotherTransaction(code);
|
||||||
|
|
||||||
|
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void execute() {
|
||||||
|
String codeToRemove = orderDTO.children.get(0).code;
|
||||||
|
Response response = orderElementService
|
||||||
|
.removeOrderElement(codeToRemove);
|
||||||
|
assertThat(response.getStatus(),
|
||||||
|
equalTo(Status.OK.getStatusCode()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
orderElementDAO.findByCode(codeToRemove);
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderElement order = orderElementDAO.findByCode(code);
|
||||||
|
assertTrue(order.getChildren().isEmpty());
|
||||||
|
} catch (InstanceNotFoundException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ public class SubcontractServiceTest {
|
||||||
assertNotNull(order.getExternalCode());
|
assertNotNull(order.getExternalCode());
|
||||||
assertThat(order.getExternalCode(), equalTo(orderLineCode));
|
assertThat(order.getExternalCode(), equalTo(orderLineCode));
|
||||||
assertThat(order.getState(),
|
assertThat(order.getState(),
|
||||||
equalTo(OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER));
|
equalTo(OrderStatusEnum.OUTSOURCED));
|
||||||
assertThat(order.getWorkHours(), equalTo(0));
|
assertThat(order.getWorkHours(), equalTo(0));
|
||||||
assertThat(order.getCustomer().getId(),
|
assertThat(order.getCustomer().getId(),
|
||||||
equalTo(externalCompany.getId()));
|
equalTo(externalCompany.getId()));
|
||||||
|
|
|
||||||
7
pom.xml
7
pom.xml
|
|
@ -505,7 +505,7 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- AspectJ -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-aop</artifactId>
|
<artifactId>spring-aop</artifactId>
|
||||||
|
|
@ -518,17 +518,18 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- AspectJ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.aspectj</groupId>
|
<groupId>org.aspectj</groupId>
|
||||||
<artifactId>aspectjtools</artifactId>
|
<artifactId>aspectjtools</artifactId>
|
||||||
<version>1.5.4</version>
|
<version>1.7.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- AspectJ (required by Spring Security) -->
|
<!-- AspectJ (required by Spring Security) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.aspectj</groupId>
|
<groupId>org.aspectj</groupId>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<artifactId>aspectjrt</artifactId>
|
||||||
<version>1.5.4</version>
|
<version>1.7.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sf.json-lib</groupId>
|
<groupId>net.sf.json-lib</groupId>
|
||||||
|
|
|
||||||
|
|
@ -47,17 +47,20 @@ methods with the following meaning:
|
||||||
* If it already exists: Update entity with new data.
|
* If it already exists: Update entity with new data.
|
||||||
* If it does not exist: Add the new entity.
|
* If it does not exist: Add the new entity.
|
||||||
|
|
||||||
These means that delete is not allowed from web services, in that way only new
|
These means that delete is not allowed for all the entities in the web services,
|
||||||
info could be added or updated. This is because of entities are related with
|
in that way only new info could be added or updated. This is because of entities
|
||||||
others and remove operation could be dangerous. Then if necessary, the
|
are related with others and remove operation could be dangerous. Anyway for some
|
||||||
recommendation would be add a field to disable such entity.
|
specific entities the delete operation has been implemented.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
These scripts are written in bash so you need to be running a bash terminal to
|
These scripts are written in bash so you need to be running a bash terminal to
|
||||||
use them.
|
use them. And they use cURL to do the HTTP requests, you can install it with the
|
||||||
|
following command in Debian based distributions::
|
||||||
|
|
||||||
|
# apt-get install curl
|
||||||
|
|
||||||
Moreover, it is recommended to have Tidy available in your system. You can
|
Moreover, it is recommended to have Tidy available in your system. You can
|
||||||
install it with the following command in Debian based distributions::
|
install it with the following command in Debian based distributions::
|
||||||
|
|
@ -205,11 +208,11 @@ For each entity there are the following methods:
|
||||||
* No parameters
|
* No parameters
|
||||||
* URL: ``/ws/rest/<service-path>/``
|
* URL: ``/ws/rest/<service-path>/``
|
||||||
|
|
||||||
* Remove entity (only available for work reports):
|
* Remove entity (only available for work reports and order elements):
|
||||||
|
|
||||||
* HTTP method: ``DELETE``
|
* HTTP method: ``DELETE``
|
||||||
* Parameter: ``entity-code``
|
* Parameter: ``entity-code``
|
||||||
* URL: ``/ws/rest/workreports/<entity-code>/``
|
* URL: ``/ws/rest/<service-path>/<entity-code>/``
|
||||||
|
|
||||||
* Special URL for work report lines:
|
* Special URL for work report lines:
|
||||||
``/ws/rest/workreports/line/<entity-code>/``
|
``/ws/rest/workreports/line/<entity-code>/``
|
||||||
|
|
|
||||||
42
scripts/rest-clients/bound-user-import-personal-timesheet.sh
Executable file
42
scripts/rest-clients/bound-user-import-personal-timesheet.sh
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./rest-common-env.sh
|
||||||
|
|
||||||
|
printf "BOUND USER\n"
|
||||||
|
printf "Username: "
|
||||||
|
read loginName
|
||||||
|
printf "Password: "
|
||||||
|
read password
|
||||||
|
|
||||||
|
file=$1
|
||||||
|
|
||||||
|
if [ "$1" = "--prod" ]; then
|
||||||
|
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||||
|
certificate=$PRODUCTION_CERTIFICATE
|
||||||
|
file=$2
|
||||||
|
elif [ "$1" = "--dev" ]; then
|
||||||
|
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||||
|
certificate=$DEVELOPMENT_CERTIFICATE
|
||||||
|
file=$2
|
||||||
|
else
|
||||||
|
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||||
|
certificate=$DEMO_CERTIFICATE
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$file" = "" ]; then
|
||||||
|
printf "Missing file\n" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
authorization=`echo -n "$loginName:$password" | base64`
|
||||||
|
|
||||||
|
result=`curl -sv -X POST $certificate -d @$file \
|
||||||
|
--header "Content-type: application/xml" \
|
||||||
|
--header "Authorization: Basic $authorization" \
|
||||||
|
$baseServiceURL/bounduser/timesheets/`
|
||||||
|
|
||||||
|
if hash tidy &> /dev/null; then
|
||||||
|
echo $result | tidy -xml -i -q -utf8
|
||||||
|
else
|
||||||
|
echo $result
|
||||||
|
fi
|
||||||
31
scripts/rest-clients/bound-user-my-tasks.sh
Executable file
31
scripts/rest-clients/bound-user-my-tasks.sh
Executable file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./rest-common-env.sh
|
||||||
|
|
||||||
|
printf "BOUND USER\n"
|
||||||
|
printf "Username: "
|
||||||
|
read loginName
|
||||||
|
printf "Password: "
|
||||||
|
read password
|
||||||
|
|
||||||
|
if [ "$1" = "--prod" ]; then
|
||||||
|
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||||
|
certificate=$PRODUCTION_CERTIFICATE
|
||||||
|
elif [ "$1" = "--dev" ]; then
|
||||||
|
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||||
|
certificate=$DEVELOPMENT_CERTIFICATE
|
||||||
|
else
|
||||||
|
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||||
|
certificate=$DEMO_CERTIFICATE
|
||||||
|
fi
|
||||||
|
|
||||||
|
authorization=`echo -n "$loginName:$password" | base64`
|
||||||
|
|
||||||
|
result=`curl -sv -X GET $certificate --header "Authorization: Basic $authorization" \
|
||||||
|
$baseServiceURL/bounduser/mytasks`
|
||||||
|
|
||||||
|
if hash tidy &> /dev/null; then
|
||||||
|
echo $result | tidy -xml -i -q -utf8
|
||||||
|
else
|
||||||
|
echo $result
|
||||||
|
fi
|
||||||
40
scripts/rest-clients/bound-user-timesheets-by-task.sh
Executable file
40
scripts/rest-clients/bound-user-timesheets-by-task.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./rest-common-env.sh
|
||||||
|
|
||||||
|
printf "BOUND USER\n"
|
||||||
|
printf "Username: "
|
||||||
|
read loginName
|
||||||
|
printf "Password: "
|
||||||
|
read password
|
||||||
|
|
||||||
|
task=$1
|
||||||
|
|
||||||
|
if [ "$1" = "--prod" ]; then
|
||||||
|
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||||
|
certificate=$PRODUCTION_CERTIFICATE
|
||||||
|
task=$2
|
||||||
|
elif [ "$1" = "--dev" ]; then
|
||||||
|
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||||
|
certificate=$DEVELOPMENT_CERTIFICATE
|
||||||
|
task=$2
|
||||||
|
else
|
||||||
|
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||||
|
certificate=$DEMO_CERTIFICATE
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$task" = "" ]; then
|
||||||
|
printf "Missing task\n" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
authorization=`echo -n "$loginName:$password" | base64`
|
||||||
|
|
||||||
|
result=`curl -sv -X GET $certificate --header "Authorization: Basic $authorization" \
|
||||||
|
$baseServiceURL/bounduser/timesheets/$task`
|
||||||
|
|
||||||
|
if hash tidy &> /dev/null; then
|
||||||
|
echo $result | tidy -xml -i -q -utf8
|
||||||
|
else
|
||||||
|
echo $result
|
||||||
|
fi
|
||||||
|
|
@ -7,19 +7,21 @@ read loginName
|
||||||
printf "Password: "
|
printf "Password: "
|
||||||
read password
|
read password
|
||||||
|
|
||||||
if [ "$3" = "--prod" ]; then
|
file=$2
|
||||||
|
|
||||||
|
if [ "$2" = "--prod" ]; then
|
||||||
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||||
certificate=$PRODUCTION_CERTIFICATE
|
certificate=$PRODUCTION_CERTIFICATE
|
||||||
elif [ "$3" = "--dev" ]; then
|
file=$3
|
||||||
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
elif [ "$2" = "--dev" ]; then
|
||||||
certificate=$DEVELOPMENT_CERTIFICATE
|
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||||
|
certificate=$DEVELOPMENT_CERTIFICATE
|
||||||
|
file=$3
|
||||||
else
|
else
|
||||||
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||||
certificate=$DEMO_CERTIFICATE
|
certificate=$DEMO_CERTIFICATE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
file=$2
|
|
||||||
|
|
||||||
if [ "$file" = "" ]; then
|
if [ "$file" = "" ]; then
|
||||||
printf "Missing file\n" 1>&2
|
printf "Missing file\n" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
4
scripts/rest-clients/personal-timesheet.xml
Normal file
4
scripts/rest-clients/personal-timesheet.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<personal-timesheet-entry-list xmlns="http://rest.ws.libreplan.org">
|
||||||
|
<personal-timesheet-entry effort="8" date="2012-11-08" task="ORDER0001-0001"/>
|
||||||
|
</personal-timesheet-entry-list>
|
||||||
3
scripts/rest-clients/remove-order-element.sh
Executable file
3
scripts/rest-clients/remove-order-element.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./remove.sh orderelements $*
|
||||||
|
|
@ -1,34 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. ./rest-common-env.sh
|
./remove.sh workreports/line $*
|
||||||
|
|
||||||
printf "Username: "
|
|
||||||
read loginName
|
|
||||||
printf "Password: "
|
|
||||||
read password
|
|
||||||
|
|
||||||
code=$1
|
|
||||||
|
|
||||||
if [ "$1" = "--prod" ]; then
|
|
||||||
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
|
||||||
certificate=$PRODUCTION_CERTIFICATE
|
|
||||||
code=$2
|
|
||||||
elif [ "$1" = "--dev" ]; then
|
|
||||||
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
|
||||||
certificate=$DEVELOPMENT_CERTIFICATE
|
|
||||||
code=$2
|
|
||||||
else
|
|
||||||
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
|
||||||
certificate=$DEMO_CERTIFICATE
|
|
||||||
fi
|
|
||||||
|
|
||||||
authorization=`echo -n "$loginName:$password" | base64`
|
|
||||||
|
|
||||||
result=`curl -sv -X DELETE $certificate --header "Authorization: Basic $authorization" \
|
|
||||||
$baseServiceURL/workreports/line/$code`
|
|
||||||
|
|
||||||
if hash tidy &> /dev/null; then
|
|
||||||
echo $result | tidy -xml -i -q -utf8
|
|
||||||
else
|
|
||||||
echo $result
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. ./rest-common-env.sh
|
./remove.sh workreports $*
|
||||||
|
|
||||||
printf "Username: "
|
|
||||||
read loginName
|
|
||||||
printf "Password: "
|
|
||||||
read password
|
|
||||||
|
|
||||||
code=$1
|
|
||||||
|
|
||||||
if [ "$1" = "--prod" ]; then
|
|
||||||
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
|
||||||
certificate=$PRODUCTION_CERTIFICATE
|
|
||||||
code=$2
|
|
||||||
elif [ "$1" = "--dev" ]; then
|
|
||||||
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
|
||||||
certificate=$DEVELOPMENT_CERTIFICATE
|
|
||||||
code=$2
|
|
||||||
else
|
|
||||||
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
|
||||||
certificate=$DEMO_CERTIFICATE
|
|
||||||
fi
|
|
||||||
|
|
||||||
authorization=`echo -n "$loginName:$password" | base64`
|
|
||||||
|
|
||||||
result=`curl -sv -X DELETE $certificate --header "Authorization: Basic $authorization" \
|
|
||||||
$baseServiceURL/workreports/$code`
|
|
||||||
|
|
||||||
if hash tidy &> /dev/null; then
|
|
||||||
echo $result | tidy -xml -i -q -utf8
|
|
||||||
else
|
|
||||||
echo $result
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
34
scripts/rest-clients/remove.sh
Executable file
34
scripts/rest-clients/remove.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./rest-common-env.sh
|
||||||
|
|
||||||
|
printf "Username: "
|
||||||
|
read loginName
|
||||||
|
printf "Password: "
|
||||||
|
read password
|
||||||
|
|
||||||
|
code=$2
|
||||||
|
|
||||||
|
if [ "$2" = "--prod" ]; then
|
||||||
|
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||||
|
certificate=$PRODUCTION_CERTIFICATE
|
||||||
|
code=$3
|
||||||
|
elif [ "$2" = "--dev" ]; then
|
||||||
|
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||||
|
certificate=$DEVELOPMENT_CERTIFICATE
|
||||||
|
code=$3
|
||||||
|
else
|
||||||
|
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||||
|
certificate=$DEMO_CERTIFICATE
|
||||||
|
fi
|
||||||
|
|
||||||
|
authorization=`echo -n "$loginName:$password" | base64`
|
||||||
|
|
||||||
|
result=`curl -sv -X DELETE $certificate --header "Authorization: Basic $authorization" \
|
||||||
|
$baseServiceURL/$1/$code`
|
||||||
|
|
||||||
|
if hash tidy &> /dev/null; then
|
||||||
|
echo $result | tidy -xml -i -q -utf8
|
||||||
|
else
|
||||||
|
echo $result
|
||||||
|
fi
|
||||||
Loading…
Add table
Reference in a new issue