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::
|
||||
|
||||
# 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::
|
||||
|
||||
# service postgresql initdb
|
||||
# service postgresql start
|
||||
# su - postgres -c "PGDATA=/var/lib/pgsql/data initdb"
|
||||
# systemctl start postgresql.service
|
||||
|
||||
.. WARNING:: Use the following commands in Fedora 16 or below::
|
||||
|
||||
# service postgresql initdb
|
||||
# service postgresql start
|
||||
|
||||
* Connect to database::
|
||||
|
||||
|
|
@ -110,11 +119,13 @@ Fedora
|
|||
|
||||
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::
|
||||
|
||||
|
|
|
|||
|
|
@ -563,4 +563,11 @@ public abstract class Task implements ITaskFundamentalProperties {
|
|||
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) {
|
||||
baseEntity.newObject = true;
|
||||
baseEntity.setNewObject(true);
|
||||
return baseEntity;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public abstract class IntegrationEntity extends BaseEntity {
|
|||
T integrationEntity, String code) {
|
||||
|
||||
BaseEntity.create(integrationEntity);
|
||||
integrationEntity.code = code;
|
||||
integrationEntity.setCode(code);
|
||||
|
||||
return integrationEntity;
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ public abstract class IntegrationEntity extends BaseEntity {
|
|||
T integrationEntity) {
|
||||
|
||||
BaseEntity.create(integrationEntity);
|
||||
integrationEntity.code = generateCode();
|
||||
integrationEntity.setCode(generateCode());
|
||||
|
||||
return integrationEntity;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ public interface IOrderElementDAO extends IIntegrationEntityDAO<OrderElement> {
|
|||
|
||||
EffortDuration calculateMinWorkedHours(final List<OrderElement> list);
|
||||
|
||||
boolean isAlreadyInUse(OrderElement orderElement);
|
||||
|
||||
boolean isAlreadyInUseThisOrAnyOfItsChildren(OrderElement orderElement);
|
||||
|
||||
/**
|
||||
|
|
@ -130,6 +132,8 @@ public interface IOrderElementDAO extends IIntegrationEntityDAO<OrderElement> {
|
|||
|
||||
boolean hasImputedExpenseSheet(Long id) throws InstanceNotFoundException;
|
||||
|
||||
boolean hasImputedExpenseSheetThisOrAnyOfItsChildren(Long id) throws InstanceNotFoundException;
|
||||
|
||||
OrderElement findByExternalCode(String code) throws InstanceNotFoundException;
|
||||
|
||||
public List<OrderElement> findByLabelsAndCriteria(Set<Label> labels,
|
||||
|
|
|
|||
|
|
@ -421,7 +421,8 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
|||
return min;
|
||||
}
|
||||
|
||||
private boolean isAlreadyInUse(OrderElement orderElement) {
|
||||
@Override
|
||||
public boolean isAlreadyInUse(OrderElement orderElement) {
|
||||
if (orderElement.isNewObject()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -518,7 +519,14 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement>
|
|||
}
|
||||
|
||||
@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);
|
||||
return (!expenseSheetLineDAO.findByOrderElementAndChildren(orderElement).isEmpty());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.hibernate.validator.Valid;
|
|||
import org.joda.time.LocalDate;
|
||||
import org.libreplan.business.advance.bootstrap.PredefinedAdvancedTypes;
|
||||
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.DirectAdvanceAssignment;
|
||||
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.trees.ITreeNode;
|
||||
import org.libreplan.business.util.deepcopy.DeepCopy;
|
||||
import org.libreplan.business.workingday.EffortDuration;
|
||||
import org.libreplan.business.workingday.IntraDayDate;
|
||||
import org.libreplan.business.workreports.daos.IWorkReportLineDAO;
|
||||
import org.libreplan.business.workreports.entities.WorkReportLine;
|
||||
|
|
@ -1630,4 +1632,23 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
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
|
||||
* 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
|
||||
* 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 Manuel Rego Casasnovas <rego@igalia.com>
|
||||
*/
|
||||
|
||||
public enum OrderStatusEnum {
|
||||
|
||||
OFFERED(_("OFFERED")), ACCEPTED(_("ACCEPTED")), STARTED(_("STARTED")), FINISHED(
|
||||
_("FINISHED")), CANCELLED(_("CANCELLED")), SUBCONTRACTED_PENDING_ORDER(
|
||||
_("SUBCONTRACTED PENDING PROJECT")), STORED(_("STORED"));
|
||||
PRE_SALES(_("PRE-SALES")),
|
||||
OFFERED(_("OFFERED")),
|
||||
OUTSOURCED(_("OUTSOURCED")),
|
||||
ACCEPTED(_("ACCEPTED")),
|
||||
STARTED(_("STARTED")),
|
||||
ON_HOLD(_("ON HOLD")),
|
||||
FINISHED(_("FINISHED")),
|
||||
CANCELLED(_("CANCELLED")),
|
||||
STORED(_("STORED"));
|
||||
|
||||
private String description;
|
||||
|
||||
|
|
@ -45,6 +51,6 @@ public enum OrderStatusEnum {
|
|||
}
|
||||
|
||||
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,
|
||||
TaskSource taskSource) {
|
||||
taskElement.taskSource = taskSource;
|
||||
taskElement.setTaskSource(taskSource);
|
||||
taskElement.updateDeadlineFromOrderElement();
|
||||
taskElement.setName(taskElement.getOrderElement().getName());
|
||||
taskElement.updateAdvancePercentageFromOrderElement();
|
||||
|
|
@ -221,6 +221,10 @@ public abstract class TaskElement extends BaseEntity {
|
|||
return taskSource;
|
||||
}
|
||||
|
||||
protected void setTaskSource(TaskSource taskSource) {
|
||||
this.taskSource = taskSource;
|
||||
}
|
||||
|
||||
protected void copyDependenciesTo(TaskElement result) {
|
||||
for (Dependency dependency : getDependenciesWithThisOrigin()) {
|
||||
Dependency.create(result, dependency.getDestination(),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public abstract class AllocationModification {
|
|||
.unmodifiableList(new ArrayList<Resource>(resources));
|
||||
}
|
||||
|
||||
private boolean hasNoResources() {
|
||||
protected boolean hasNoResources() {
|
||||
return resourcesOnWhichApplyAllocation.isEmpty();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public interface IWorkerDAO extends IIntegrationEntityDAO<Worker> {
|
|||
List<Worker> findByFirstNameSecondNameAndNifAnotherTransaction(
|
||||
String firstname, String surname, String nif);
|
||||
|
||||
List<Object[]> getWorkingHoursGroupedPerWorker(List<String> workerNifs,
|
||||
List<Object[]> getWorkingHoursGroupedPerWorker(List<String> workerCodes,
|
||||
Date startingDate, Date endingDate);
|
||||
|
||||
Worker findByNifAnotherTransaction(String nif)
|
||||
|
|
|
|||
|
|
@ -147,8 +147,8 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
|||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<Object[]> getWorkingHoursGroupedPerWorker(
|
||||
List<String> workerNifs, Date startingDate, Date endingDate) {
|
||||
String strQuery = "SELECT worker.nif, SUM(wrl.effort) "
|
||||
List<String> workerCodes, Date startingDate, Date endingDate) {
|
||||
String strQuery = "SELECT worker.code, SUM(wrl.effort) "
|
||||
+ "FROM Worker worker, WorkReportLine wrl "
|
||||
+ "LEFT OUTER JOIN wrl.resource resource "
|
||||
+ "WHERE resource.id = worker.id ";
|
||||
|
|
@ -165,15 +165,15 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
|||
}
|
||||
|
||||
// Set workers
|
||||
if (workerNifs != null && !workerNifs.isEmpty()) {
|
||||
strQuery += "AND worker.nif IN (:workerNifs) ";
|
||||
if (workerCodes != null && !workerCodes.isEmpty()) {
|
||||
strQuery += "AND worker.code IN (:workerCodes) ";
|
||||
}
|
||||
|
||||
// Group by
|
||||
strQuery += "GROUP BY worker.nif ";
|
||||
strQuery += "GROUP BY worker.code ";
|
||||
|
||||
// Order by
|
||||
strQuery += "ORDER BY worker.nif";
|
||||
strQuery += "ORDER BY worker.code";
|
||||
|
||||
// Set parameters
|
||||
Query query = getSession().createQuery(strQuery);
|
||||
|
|
@ -183,8 +183,8 @@ public class WorkerDAO extends IntegrationEntityDAO<Worker>
|
|||
if (endingDate != null) {
|
||||
query.setParameter("endingDate", endingDate);
|
||||
}
|
||||
if (workerNifs != null && !workerNifs.isEmpty()) {
|
||||
query.setParameterList("workerNifs", workerNifs);
|
||||
if (workerCodes != null && !workerCodes.isEmpty()) {
|
||||
query.setParameterList("workerCodes", workerCodes);
|
||||
}
|
||||
|
||||
// Get result
|
||||
|
|
|
|||
|
|
@ -107,18 +107,18 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
.getInitDate());
|
||||
Days fromBeginningToEnd = daysBetween(order.getInitDate(), origin
|
||||
.getDeadline());
|
||||
beingBuilt.materialAssignments = copyMaterialAssignmentsFrom(beingBuilt, origin
|
||||
.getMaterialAssignments());
|
||||
beingBuilt.criterionRequirements = copyDirectCriterionRequirements(
|
||||
beingBuilt, origin.getDirectCriterionRequirement());
|
||||
beingBuilt.labels = new HashSet<Label>(origin.getLabels());
|
||||
beingBuilt.qualityForms = origin.getQualityForms();
|
||||
beingBuilt.advanceAssignmentTemplates = copyDirectAdvanceAssignments(
|
||||
beingBuilt, origin.getDirectAdvanceAssignments());
|
||||
beingBuilt.infoComponent = infoComponentCopied;
|
||||
beingBuilt.schedulingStateType = origin.getSchedulingStateType();
|
||||
beingBuilt.setMaterialAssignments(copyMaterialAssignmentsFrom(beingBuilt, origin
|
||||
.getMaterialAssignments()));
|
||||
beingBuilt.setCriterionRequirements(copyDirectCriterionRequirements(
|
||||
beingBuilt, origin.getDirectCriterionRequirement()));
|
||||
beingBuilt.addLabels(origin.getLabels());
|
||||
beingBuilt.setQualityForms(origin.getQualityForms());
|
||||
beingBuilt.setAdvanceAssignmentTemplates(copyDirectAdvanceAssignments(
|
||||
beingBuilt, origin.getDirectAdvanceAssignments()));
|
||||
beingBuilt.setInfoComponent(infoComponentCopied);
|
||||
beingBuilt.setSchedulingStateType(origin.getSchedulingStateType());
|
||||
assignDates(beingBuilt, fromBeginningToStart, fromBeginningToEnd);
|
||||
beingBuilt.origin = origin;
|
||||
beingBuilt.setOrigin(origin);
|
||||
return create(beingBuilt);
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
}
|
||||
|
||||
public static <T extends OrderElementTemplate> T createNew(T beingBuilt) {
|
||||
beingBuilt.infoComponent = new InfoComponent();
|
||||
beingBuilt.setInfoComponent(new InfoComponent());
|
||||
assignDates(beingBuilt, null, null);
|
||||
return create(beingBuilt);
|
||||
}
|
||||
|
|
@ -314,6 +314,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
return schedulingStateType;
|
||||
}
|
||||
|
||||
protected void setSchedulingStateType(SchedulingState.Type schedulingStateType) {
|
||||
this.schedulingStateType = schedulingStateType;
|
||||
}
|
||||
|
||||
public OrderLineGroupTemplate getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
|
@ -322,13 +326,17 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
this.parent = parent;
|
||||
}
|
||||
|
||||
private InfoComponent getInfoComponent() {
|
||||
protected InfoComponent getInfoComponent() {
|
||||
if (infoComponent == null) {
|
||||
infoComponent = new InfoComponent();
|
||||
}
|
||||
return infoComponent;
|
||||
}
|
||||
|
||||
protected void setInfoComponent(InfoComponent infoComponent) {
|
||||
this.infoComponent = infoComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
protected void setMaterialAssignments(Set<MaterialAssignmentTemplate> materialAssigments) {
|
||||
this.materialAssignments = materialAssignments;
|
||||
}
|
||||
|
||||
public void addMaterialAssignment(
|
||||
MaterialAssignmentTemplate materialAssignment) {
|
||||
Validate.notNull(materialAssignment);
|
||||
|
|
@ -429,6 +441,11 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
this.labels.add(label);
|
||||
}
|
||||
|
||||
public void addLabels(Collection<Label> labels){
|
||||
Validate.notNull(labels);
|
||||
this.labels.addAll(labels);
|
||||
}
|
||||
|
||||
public void removeLabel(Label label) {
|
||||
this.labels.remove(label);
|
||||
}
|
||||
|
|
@ -437,6 +454,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
return Collections.unmodifiableSet(qualityForms);
|
||||
}
|
||||
|
||||
protected void setQualityForms(Set<QualityForm> qualityForms) {
|
||||
this.qualityForms = qualityForms;
|
||||
}
|
||||
|
||||
public void addQualityForm(QualityForm qualityForm) {
|
||||
qualityForms.add(qualityForm);
|
||||
}
|
||||
|
|
@ -450,6 +471,11 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
return Collections.unmodifiableSet(advanceAssignmentTemplates);
|
||||
}
|
||||
|
||||
protected void setAdvanceAssignmentTemplates(
|
||||
Set<AdvanceAssignmentTemplate> advanceAssignmentTemplates) {
|
||||
this.advanceAssignmentTemplates = advanceAssignmentTemplates;
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
return getParent() == null;
|
||||
}
|
||||
|
|
@ -497,6 +523,10 @@ public abstract class OrderElementTemplate extends BaseEntity implements
|
|||
return Collections.unmodifiableSet(criterionRequirements);
|
||||
}
|
||||
|
||||
protected void setCriterionRequirements(Set<CriterionRequirement> criterionRequirements) {
|
||||
this.criterionRequirements = criterionRequirements;
|
||||
}
|
||||
|
||||
public abstract List<HoursGroup> getHoursGroups();
|
||||
|
||||
public abstract Integer getWorkHours();
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
|||
OrderElementTemplate.create(beingBuilt, group);
|
||||
List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt,
|
||||
group.getChildren());
|
||||
beingBuilt.children = result;
|
||||
beingBuilt.setChildren(result);
|
||||
beingBuilt.propagateIndirectCriterionRequirements();
|
||||
return beingBuilt;
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
|||
* and it's needed to propagate its criteria while preserving the original
|
||||
* value of 'valid' field in {@link IndirectCriterionRequirement}
|
||||
*/
|
||||
private void propagateIndirectCriterionRequirements() {
|
||||
protected void propagateIndirectCriterionRequirements() {
|
||||
propagateIndirectCriterionRequirementsForOrderLineGroup(this);
|
||||
propagateIndirectCriterionRequirementsForOrderLines(this);
|
||||
}
|
||||
|
|
@ -217,6 +217,10 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
|
|||
return Collections.unmodifiableList(children);
|
||||
}
|
||||
|
||||
protected void setChildren(List<OrderElementTemplate> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITreeParentNode<OrderElementTemplate> toContainer() {
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -59,4 +59,7 @@ public interface IWorkReportDAO extends IIntegrationEntityDAO<WorkReport> {
|
|||
|
||||
boolean isAnyPersonalTimesheetAlreadySaved();
|
||||
|
||||
List<WorkReport> findPersonalTimesheetsByResourceAndOrderElement(
|
||||
Resource resource);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,4 +74,7 @@ public interface IWorkReportLineDAO extends
|
|||
|
||||
Boolean isFinished(OrderElement orderElement);
|
||||
|
||||
List<WorkReportLine> findByOrderElementAndWorkReports(
|
||||
OrderElement orderElement, List<WorkReport> workReports);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,19 +143,9 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
|||
@SuppressWarnings("unchecked")
|
||||
public WorkReport getPersonalTimesheetWorkReport(Resource resource,
|
||||
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.add(Restrictions.eq("workReportType", workReportType));
|
||||
criteria.add(Restrictions.eq("workReportType",
|
||||
getPersonalTimesheetsWorkReportType()));
|
||||
List<WorkReport> personalTimesheets = criteria.add(
|
||||
Restrictions.eq("resource", resource)).list();
|
||||
|
||||
|
|
@ -179,8 +169,7 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyPersonalTimesheetAlreadySaved() {
|
||||
private WorkReportType getPersonalTimesheetsWorkReportType() {
|
||||
WorkReportType workReportType;
|
||||
try {
|
||||
workReportType = workReportTypeDAO
|
||||
|
|
@ -191,10 +180,29 @@ public class WorkReportDAO extends IntegrationEntityDAO<WorkReport>
|
|||
} catch (InstanceNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return workReportType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnyPersonalTimesheetAlreadySaved() {
|
||||
WorkReportType workReportType = getPersonalTimesheetsWorkReportType();
|
||||
|
||||
Criteria criteria = getSession().createCriteria(WorkReport.class);
|
||||
criteria.add(Restrictions.eq("workReportType", workReportType));
|
||||
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;
|
||||
}
|
||||
|
||||
@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" />
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@
|
|||
access="field"
|
||||
cascade="all"
|
||||
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"
|
||||
access="field"
|
||||
|
|
|
|||
|
|
@ -48,8 +48,12 @@ public class ConcurrentModificationController extends GenericForwardComposer {
|
|||
.info(
|
||||
"an OptimistLockingFailureException caused a disruption to an user",
|
||||
exception);
|
||||
Executions.sendRedirect("/common/concurrent_modification.zul?back="
|
||||
+ backURL);
|
||||
if (Executions.getCurrent() != null) {
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public interface IOrderModel extends IIntegrationEntityModel {
|
|||
|
||||
PlanningState getPlanningState();
|
||||
|
||||
boolean hasImputedExpenseSheets(OrderElement order);
|
||||
boolean hasImputedExpenseSheetsThisOrAnyOfItsChildren(OrderElement order);
|
||||
|
||||
void removeAskedEndDate(EndDateCommunication endDate);
|
||||
|
||||
|
|
@ -145,4 +145,7 @@ public interface IOrderModel extends IIntegrationEntityModel {
|
|||
|
||||
boolean isAnyTaskWithConstraint(PositionConstraintType type);
|
||||
|
||||
boolean isOnlyChildAndParentAlreadyInUseByHoursOrExpenses(
|
||||
OrderElement orderElement);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -843,7 +843,7 @@ public class OrderCRUDController extends GenericForwardComposer {
|
|||
}
|
||||
|
||||
private void remove(Order order) {
|
||||
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheets(order);
|
||||
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheetsThisOrAnyOfItsChildren(order);
|
||||
if (hasImputedExpenseSheets) {
|
||||
messagesForUser
|
||||
.showMessage(
|
||||
|
|
|
|||
|
|
@ -702,7 +702,8 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
|
||||
@Override
|
||||
public void remove(OrderElement element) {
|
||||
boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheets(element);
|
||||
boolean hasImputedExpenseSheets = orderModel
|
||||
.hasImputedExpenseSheetsThisOrAnyOfItsChildren(element);
|
||||
if (hasImputedExpenseSheets) {
|
||||
messagesForUser
|
||||
.showMessage(
|
||||
|
|
@ -719,10 +720,22 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
Level.ERROR,
|
||||
_("You cannot remove the task \"{0}\" because it has work reported on it or any of its children",
|
||||
element.getName()));
|
||||
} else {
|
||||
super.remove(element);
|
||||
getRenderer().removeCodeTextbox(element);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -869,12 +869,12 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean hasImputedExpenseSheets(OrderElement order) {
|
||||
public boolean hasImputedExpenseSheetsThisOrAnyOfItsChildren(OrderElement order) {
|
||||
if (order.isNewObject()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return orderElementDAO.hasImputedExpenseSheet(order.getId());
|
||||
return orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(order.getId());
|
||||
} catch (InstanceNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
@ -931,4 +931,24 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
|||
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,
|
||||
OrderStatusEnum.OFFERED, OrderStatusEnum.STARTED,
|
||||
OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER).contains(
|
||||
OrderStatusEnum.OUTSOURCED).contains(
|
||||
state)) {
|
||||
if (taskElement.getAssignedStatus() == "assigned") {
|
||||
cssClass = "order-open-assigned";
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
|
|||
private static final EnumSet<OrderStatusEnum> STATUS_VISUALIZED = EnumSet
|
||||
.of(OrderStatusEnum.ACCEPTED, OrderStatusEnum.OFFERED,
|
||||
OrderStatusEnum.STARTED,
|
||||
OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER);
|
||||
OrderStatusEnum.OUTSOURCED);
|
||||
|
||||
public void setPlanningControllerEntryPoints(
|
||||
MultipleTabsPlannerController entryPoints) {
|
||||
|
|
|
|||
|
|
@ -217,7 +217,10 @@ public class PlanningStateCreator {
|
|||
|
||||
public PlanningState retrieveOrCreate(Desktop desktop, Order order,
|
||||
IActionsOnRetrieval onRetrieval) {
|
||||
Object existent = desktop.getAttribute(ATTRIBUTE_NAME);
|
||||
Object existent = null;
|
||||
if (desktop != null) {
|
||||
existent = desktop.getAttribute(ATTRIBUTE_NAME);
|
||||
}
|
||||
if (existent instanceof PlanningState) {
|
||||
PlanningState result = (PlanningState) existent;
|
||||
if (ObjectUtils.equals(order.getId(), result.getOrder().getId())) {
|
||||
|
|
@ -230,7 +233,9 @@ public class PlanningStateCreator {
|
|||
}
|
||||
PlanningState result = createPlanning(reload(order));
|
||||
result.onRetrieval();
|
||||
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
||||
if (desktop != null) {
|
||||
desktop.setAttribute(ATTRIBUTE_NAME, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -316,6 +316,10 @@ public class EditTaskController extends GenericForwardComposer {
|
|||
if (context.getRelativeTo() instanceof TaskComponent) {
|
||||
((TaskComponent) context.getRelativeTo()).updateProperties();
|
||||
((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()) {
|
||||
// Then a new container will be created
|
||||
nameTextbox = getRenderer().getNameTextbox(node);
|
||||
} else {
|
||||
// select the parent row to add new children ASAP
|
||||
tree.setSelectedItem(getRenderer().getTreeitemForNode(
|
||||
newNode.getParent().getThis()));
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
return new Constraint() {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@ import javax.annotation.Resource;
|
|||
|
||||
import org.joda.time.LocalDate;
|
||||
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.orders.entities.OrderElement;
|
||||
import org.libreplan.business.orders.entities.SumChargedEffort;
|
||||
import org.libreplan.business.planner.entities.Task;
|
||||
import org.libreplan.business.workingday.EffortDuration;
|
||||
import org.libreplan.web.common.Util;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
|
|
@ -75,21 +72,15 @@ public class MyTasksAreaController extends GenericForwardComposer {
|
|||
|
||||
Util.appendLabel(row, getProgress(orderElement));
|
||||
|
||||
Util.appendLabel(row, getEffort(orderElement));
|
||||
Util.appendLabel(row, _("{0} h", orderElement.getEffortAsString()));
|
||||
|
||||
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) {
|
||||
|
||||
AdvanceMeasurement lastAdvanceMeasurement = getLastAdvanceMeasurement(orderElement);
|
||||
AdvanceMeasurement lastAdvanceMeasurement = orderElement
|
||||
.getLastAdvanceMeasurement();
|
||||
if (lastAdvanceMeasurement != null) {
|
||||
return MessageFormat.format("[{0} %] ({1})",
|
||||
lastAdvanceMeasurement.getValue(),
|
||||
|
|
@ -98,17 +89,6 @@ public class MyTasksAreaController extends GenericForwardComposer {
|
|||
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) {
|
||||
EventListener trackTimeButtonListener = new EventListener() {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import org.libreplan.business.resources.entities.Resource;
|
||||
import org.libreplan.business.users.entities.User;
|
||||
import org.libreplan.web.UserUtil;
|
||||
|
||||
/**
|
||||
* Utilities class for user dashboard window
|
||||
|
|
@ -38,4 +39,12 @@ public class UserDashboardUtil {
|
|||
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 removeOrderElement(String code);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,18 +21,28 @@
|
|||
|
||||
package org.libreplan.ws.orders.impl;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
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.libreplan.business.common.daos.IIntegrationEntityDAO;
|
||||
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.libreplan.business.common.exceptions.ValidationException;
|
||||
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.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.OrderDTO;
|
||||
import org.libreplan.ws.common.impl.ConfigurationOrderElementConverter;
|
||||
|
|
@ -60,6 +70,12 @@ public class OrderElementServiceREST extends
|
|||
@Autowired
|
||||
private IOrderDAO orderDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderElementDAO orderElementDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderModel orderModel;
|
||||
|
||||
@Override
|
||||
@GET
|
||||
@Transactional(readOnly = true)
|
||||
|
|
@ -108,4 +124,95 @@ public class OrderElementServiceREST extends
|
|||
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);
|
||||
}
|
||||
|
||||
List<String> workerNifs = null;
|
||||
List<String> workerCodes = null;
|
||||
if (resourceCode != null) {
|
||||
workerNifs = Arrays.asList(resourceCode);
|
||||
workerCodes = Arrays.asList(resourceCode);
|
||||
}
|
||||
|
||||
List<Object[]> hoursPerWorker = workerDAO
|
||||
.getWorkingHoursGroupedPerWorker(workerNifs, startingDate,
|
||||
.getWorkingHoursGroupedPerWorker(workerCodes, startingDate,
|
||||
endingDate);
|
||||
|
||||
for (Object[] pair : hoursPerWorker) {
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ public class SubcontractServiceREST implements ISubcontractService {
|
|||
order.setCode(code);
|
||||
generateCodes(order);
|
||||
|
||||
order.setState(OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER);
|
||||
order.setState(OrderStatusEnum.OUTSOURCED);
|
||||
|
||||
if (subcontractedTaskDataDTO.workDescription != null) {
|
||||
order.setName(subcontractedTaskDataDTO.workDescription);
|
||||
|
|
|
|||
|
|
@ -73,11 +73,13 @@
|
|||
<ref bean="materialServiceREST"/>
|
||||
<ref bean="unitTypeServiceREST"/>
|
||||
<ref bean="expenseSheetServiceREST"/>
|
||||
<ref bean="boundUserServiceREST"/>
|
||||
</jaxrs:serviceBeans>
|
||||
<jaxrs:providers>
|
||||
<ref bean="runtimeExceptionMapper" />
|
||||
<ref bean="instanceNotFoundExceptionMapper" />
|
||||
<ref bean="incompatibleTypeExceptionMapper" />
|
||||
<ref bean="hibernateOptimisticLockingFailureException" />
|
||||
</jaxrs:providers>
|
||||
<!-- FIXME: in root pom.xml, enable CXF logging on development and
|
||||
disable it in production.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@
|
|||
entry-point-ref="customAuthenticationEntryPoint">
|
||||
|
||||
<!-- 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/**"
|
||||
access="ROLE_WS_SUBCONTRACTING"
|
||||
method="GET" />
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ import java.util.SortedSet;
|
|||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.joda.time.LocalDate;
|
||||
|
|
@ -536,6 +538,18 @@ public class OrderElementServiceTest {
|
|||
public void validOrderWithOrderLineGroup() {
|
||||
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.name = "Order name " + UUID.randomUUID().toString();
|
||||
orderDTO.code = code;
|
||||
|
|
@ -557,6 +571,14 @@ public class OrderElementServiceTest {
|
|||
orderLineGroupDTO.children.add(orderLineDTO);
|
||||
|
||||
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);
|
||||
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = orderElementService
|
||||
|
|
@ -565,6 +587,32 @@ public class OrderElementServiceTest {
|
|||
instanceConstraintViolationsList.size() == 0);
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ public class SubcontractServiceTest {
|
|||
assertNotNull(order.getExternalCode());
|
||||
assertThat(order.getExternalCode(), equalTo(orderLineCode));
|
||||
assertThat(order.getState(),
|
||||
equalTo(OrderStatusEnum.SUBCONTRACTED_PENDING_ORDER));
|
||||
equalTo(OrderStatusEnum.OUTSOURCED));
|
||||
assertThat(order.getWorkHours(), equalTo(0));
|
||||
assertThat(order.getCustomer().getId(),
|
||||
equalTo(externalCompany.getId()));
|
||||
|
|
|
|||
7
pom.xml
7
pom.xml
|
|
@ -505,7 +505,7 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- AspectJ -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
|
|
@ -518,17 +518,18 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- AspectJ -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>1.5.4</version>
|
||||
<version>1.7.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AspectJ (required by Spring Security) -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.5.4</version>
|
||||
<version>1.7.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<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 does not exist: Add the new entity.
|
||||
|
||||
These means that delete is not allowed from web services, in that way only new
|
||||
info could be added or updated. This is because of entities are related with
|
||||
others and remove operation could be dangerous. Then if necessary, the
|
||||
recommendation would be add a field to disable such entity.
|
||||
These means that delete is not allowed for all the entities in the web services,
|
||||
in that way only new info could be added or updated. This is because of entities
|
||||
are related with others and remove operation could be dangerous. Anyway for some
|
||||
specific entities the delete operation has been implemented.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
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
|
||||
install it with the following command in Debian based distributions::
|
||||
|
|
@ -205,11 +208,11 @@ For each entity there are the following methods:
|
|||
* No parameters
|
||||
* 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``
|
||||
* Parameter: ``entity-code``
|
||||
* URL: ``/ws/rest/workreports/<entity-code>/``
|
||||
* URL: ``/ws/rest/<service-path>/<entity-code>/``
|
||||
|
||||
* Special URL for work report lines:
|
||||
``/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: "
|
||||
read password
|
||||
|
||||
if [ "$3" = "--prod" ]; then
|
||||
file=$2
|
||||
|
||||
if [ "$2" = "--prod" ]; then
|
||||
baseServiceURL=$PRODUCTION_BASE_SERVICE_URL
|
||||
certificate=$PRODUCTION_CERTIFICATE
|
||||
elif [ "$3" = "--dev" ]; then
|
||||
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||
certificate=$DEVELOPMENT_CERTIFICATE
|
||||
file=$3
|
||||
elif [ "$2" = "--dev" ]; then
|
||||
baseServiceURL=$DEVELOPMENT_BASE_SERVICE_URL
|
||||
certificate=$DEVELOPMENT_CERTIFICATE
|
||||
file=$3
|
||||
else
|
||||
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||
certificate=$DEMO_CERTIFICATE
|
||||
baseServiceURL=$DEMO_BASE_SERVICE_URL
|
||||
certificate=$DEMO_CERTIFICATE
|
||||
fi
|
||||
|
||||
file=$2
|
||||
|
||||
if [ "$file" = "" ]; then
|
||||
printf "Missing file\n" 1>&2
|
||||
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
|
||||
|
||||
. ./rest-common-env.sh
|
||||
|
||||
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
|
||||
./remove.sh workreports/line $*
|
||||
|
|
|
|||
|
|
@ -1,34 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
. ./rest-common-env.sh
|
||||
|
||||
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
|
||||
./remove.sh workreports $*
|
||||
|
|
|
|||
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