From e15bdb2e28e4f104869838f374697a323ec9c2b6 Mon Sep 17 00:00:00 2001 From: Vova Perebykivskiy Date: Mon, 4 Apr 2016 17:01:55 +0300 Subject: [PATCH] Extend the statistics to be sent to LibrePlan server. Code refactoring. --- .../orders/entities/OrderElement.java | 22 ++- .../entities/TaskQualityFormItem.java | 11 +- .../web/common/ConfigurationController.java | 51 ++++-- .../web/common/GatheredUsageStats.java | 125 +++++++++++---- .../web/materials/MaterialsModel.java | 33 ++-- ...kQualityFormsToOrderElementController.java | 15 +- ...edTaskQualityFormsToOrderElementModel.java | 146 +++++++++--------- ...edTaskQualityFormsToOrderElementModel.java | 6 + .../web/orders/OrderCRUDController.java | 54 +++---- .../org/libreplan/web/orders/OrderModel.java | 7 +- .../tabs/MultipleTabsPlannerController.java | 65 ++++++-- .../web/qualityforms/QualityFormModel.java | 2 +- .../web/resources/worker/WorkerModel.java | 7 +- .../libreplan/web/security/SecurityUtils.java | 4 + 14 files changed, 341 insertions(+), 207 deletions(-) diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java index 3fbf8ac7b..dd698391a 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java @@ -83,8 +83,7 @@ import org.libreplan.business.workingday.IntraDayDate; import org.libreplan.business.workreports.daos.IWorkReportLineDAO; import org.libreplan.business.workreports.entities.WorkReportLine; -public abstract class OrderElement extends IntegrationEntity implements - ICriterionRequirable, ITreeNode { +public abstract class OrderElement extends IntegrationEntity implements ICriterionRequirable, ITreeNode { protected InfoComponentWithCode infoComponent = new InfoComponentWithCode(); @@ -1119,7 +1118,7 @@ public abstract class OrderElement extends IntegrationEntity implements } public Order getOrder() { - if (parent == null) { + if ( parent == null ) { return null; } return parent.getOrder(); @@ -1142,11 +1141,9 @@ public abstract class OrderElement extends IntegrationEntity implements this.taskQualityForms = taskQualityForms; } - public TaskQualityForm addTaskQualityForm(QualityForm qualityForm) - throws ValidationException { + public TaskQualityForm addTaskQualityForm(QualityForm qualityForm) throws ValidationException { ckeckUniqueQualityForm(qualityForm); - TaskQualityForm taskQualityForm = TaskQualityForm.create(this, - qualityForm); + TaskQualityForm taskQualityForm = TaskQualityForm.create(this, qualityForm); this.taskQualityForms.add(taskQualityForm); return taskQualityForm; } @@ -1155,14 +1152,15 @@ public abstract class OrderElement extends IntegrationEntity implements this.taskQualityForms.remove(taskQualityForm); } - private void ckeckUniqueQualityForm(QualityForm qualityForm) - throws ValidationException, IllegalArgumentException { + private void ckeckUniqueQualityForm(QualityForm qualityForm) throws ValidationException, IllegalArgumentException { Validate.notNull(qualityForm); for (TaskQualityForm taskQualityForm : getTaskQualityForms()) { - if (qualityForm.equals(taskQualityForm.getQualityForm())) { + if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) { throw new ValidationException(ValidationException.invalidValue( - _("Quality form already exists"), "name", - qualityForm.getName(), qualityForm)); + _("Quality form already exists"), + "name", + qualityForm.getName(), + qualityForm)); } } } diff --git a/libreplan-business/src/main/java/org/libreplan/business/qualityforms/entities/TaskQualityFormItem.java b/libreplan-business/src/main/java/org/libreplan/business/qualityforms/entities/TaskQualityFormItem.java index 54e47abdf..c0b1e49a5 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/qualityforms/entities/TaskQualityFormItem.java +++ b/libreplan-business/src/main/java/org/libreplan/business/qualityforms/entities/TaskQualityFormItem.java @@ -38,8 +38,7 @@ public class TaskQualityFormItem implements INewObject { public final static String propertyPassed = "passed"; static TaskQualityFormItem create(QualityFormItem qualityFormItem) { - TaskQualityFormItem taskQualityFormItem = new TaskQualityFormItem( - qualityFormItem); + TaskQualityFormItem taskQualityFormItem = new TaskQualityFormItem(qualityFormItem); taskQualityFormItem.setNewObject(true); return taskQualityFormItem; } @@ -125,11 +124,11 @@ public class TaskQualityFormItem implements INewObject { @AssertTrue(message = "percentage should be greater than 0% and less than 100%") public boolean isQualityFormItemPercentageConstraint() { - if (percentage == null) { + if ( percentage == null ) { return true; } - if ((percentage.compareTo(new BigDecimal(100).setScale(2)) <= 0) - && (percentage.compareTo(new BigDecimal(0).setScale(2)) > 0)) { + if ( (percentage.compareTo(new BigDecimal(100).setScale(2)) <= 0) && + (percentage.compareTo(new BigDecimal(0).setScale(2)) > 0) ) { return true; } return false; @@ -137,7 +136,7 @@ public class TaskQualityFormItem implements INewObject { @AssertTrue(message = "date not specified") public boolean isIfDateCanBeNullConstraint() { - if ((passed == null) || (!passed)) { + if ( (passed == null) || (!passed) ) { return true; } else { return (date != null); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java index 33f30b118..2eb95069b 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/ConfigurationController.java @@ -68,6 +68,14 @@ import org.libreplan.importers.JiraRESTClient; import org.libreplan.importers.TimSoapClient; import org.libreplan.web.common.components.bandboxsearch.BandboxSearch; import org.libreplan.web.orders.IOrderModel; +import org.libreplan.web.expensesheet.IExpenseSheetModel; +import org.libreplan.web.materials.IMaterialsModel; +import org.libreplan.web.orders.IAssignedTaskQualityFormsToOrderElementModel; +import org.libreplan.web.resources.machine.IMachineModel; +import org.libreplan.web.resources.worker.IWorkerModel; +import org.libreplan.web.security.SecurityUtils; +import org.libreplan.web.workreports.IWorkReportModel; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.DefaultDirObjectFactory; @@ -115,8 +123,7 @@ import org.zkoss.zul.impl.InputElement; */ public class ConfigurationController extends GenericForwardComposer { - private static final Log LOG = LogFactory - .getLog(ConfigurationController.class); + private static final Log LOG = LogFactory.getLog(ConfigurationController.class); private final ProgressTypeRenderer progressTypeRenderer = new ProgressTypeRenderer(); @@ -134,6 +141,24 @@ public class ConfigurationController extends GenericForwardComposer { private IOrderModel orderModel; + @Autowired + private IWorkReportModel workReportModel; + + @Autowired + private IWorkerModel workerModel; + + @Autowired + private IMachineModel machineModel; + + @Autowired + private IExpenseSheetModel expenseSheetModel; + + @Autowired + private IMaterialsModel materialsModel; + + @Autowired + private IAssignedTaskQualityFormsToOrderElementModel assignedQualityFormsModel; + private IMessagesForUser messages; private Component messagesContainer; @@ -166,8 +191,6 @@ public class ConfigurationController extends GenericForwardComposer { private Textbox emailSenderTextbox; - private boolean isGatheredStatsAlreadySent = false; - @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); @@ -266,13 +289,9 @@ public class ConfigurationController extends GenericForwardComposer { messages.showMessage(Level.INFO, _("Changes saved")); // Send data to server - if (!isGatheredStatsAlreadySent && configurationDAO.getConfigurationWithReadOnlyTransaction() - .isAllowToGatherUsageStatsEnabled()) { - GatheredUsageStats gatheredUsageStats = new GatheredUsageStats(); - gatheredUsageStats.setupNotAutowiredClasses(userDAO, orderModel); - gatheredUsageStats.sendGatheredUsageStatsToServer(); - isGatheredStatsAlreadySent = true; - } + if ( !SecurityUtils.isGatheredStatsAlreadySent && + configurationDAO.getConfigurationWithReadOnlyTransaction().isAllowToGatherUsageStatsEnabled() ) + sendDataToServer(); if (getSelectedConnector() != null && !configurationModel @@ -297,6 +316,16 @@ public class ConfigurationController extends GenericForwardComposer { } } + private void sendDataToServer(){ + GatheredUsageStats gatheredUsageStats = new GatheredUsageStats(); + + gatheredUsageStats.setupNotAutowiredClasses(userDAO, orderModel, workReportModel, workerModel, machineModel, + expenseSheetModel, materialsModel, assignedQualityFormsModel); + + gatheredUsageStats.sendGatheredUsageStatsToServer(); + SecurityUtils.isGatheredStatsAlreadySent = true; + } + public void cancel() throws InterruptedException { configurationModel.cancel(); messages.clearMessages(); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/common/GatheredUsageStats.java b/libreplan-webapp/src/main/java/org/libreplan/web/common/GatheredUsageStats.java index c8532d396..b2b54f817 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/common/GatheredUsageStats.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/common/GatheredUsageStats.java @@ -3,6 +3,12 @@ package org.libreplan.web.common; import org.libreplan.business.common.VersionInformation; import org.libreplan.business.users.daos.IUserDAO; import org.libreplan.web.orders.IOrderModel; +import org.libreplan.web.expensesheet.IExpenseSheetModel; +import org.libreplan.web.materials.IMaterialsModel; +import org.libreplan.web.orders.IAssignedTaskQualityFormsToOrderElementModel; +import org.libreplan.web.resources.machine.IMachineModel; +import org.libreplan.web.resources.worker.IWorkerModel; +import org.libreplan.web.workreports.IWorkReportModel; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.zkoss.json.JSONObject; @@ -28,7 +34,7 @@ import java.util.Properties; * * Created by * @author Vova Perebykivskiy - * on 02/08/2016. + * on 02.08.2016. */ public class GatheredUsageStats { @@ -37,9 +43,22 @@ public class GatheredUsageStats { private IOrderModel orderModel; + private IWorkReportModel workReportModel; - // Version of this statistics implementation - private int jsonObjectVersion = 1; + private IWorkerModel workerModel; + + private IMachineModel machineModel; + + private IExpenseSheetModel expenseSheetModel; + + private IMaterialsModel materialsModel; + + private IAssignedTaskQualityFormsToOrderElementModel assignedQualityFormModel; + + + // Version of this statistics implementation. + // Just increment it, if you will change something related to JSON object. + private int jsonObjectVersion = 2; // Unique system identifier (MD5 - ip + hostname) private String id; @@ -53,9 +72,24 @@ public class GatheredUsageStats { // Number of projects in application private int projects; - private Number getUserRows(){ - return userDAO.getRowCount(); - } + // Number of timesheets in application + private int timesheets; + + // Number of workers in application + private int workers; + + // Number of machines in application + private int machines; + + // Number of expense sheets in application + private int expensesheets; + + // Number of materials in application + private int materials; + + // Number of assigned quality forms in application + private int assignedQualityForms; + private String generateID(){ // Make hash of ip + hostname @@ -77,8 +111,8 @@ public class GatheredUsageStats { // Convert bytes to hex format sb = new StringBuffer(); - for (int i = 0; i < encoded.length; i++) sb.append(Integer.toString((encoded[i] & 0xff) + 0x100, 16) - .substring(1)); + for (int i = 0; i < encoded.length; i++) + sb.append(Integer.toString((encoded[i] & 0xff) + 0x100, 16).substring(1)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); @@ -93,6 +127,12 @@ public class GatheredUsageStats { setId(generateID()); setUsers(getUserRows()); setProjects(orderModel.getOrders().size()); + setTimesheets(workReportModel.getWorkReportDTOs().size()); + setWorkers(workerModel.getWorkers().size()); + setMachines(machineModel.getMachines().size()); + setExpensesheets(expenseSheetModel.getExpenseSheets().size()); + setMaterials(materialsModel.getMaterials().size()); + setQualityForms(assignedQualityFormModel.getAssignedQualityForms().size()); } public void sendGatheredUsageStatsToServer(){ @@ -103,6 +143,12 @@ public class GatheredUsageStats { json.put("version", version); json.put("users", users); json.put("projects", projects); + json.put("timesheets", timesheets); + json.put("workers", workers); + json.put("machines", machines); + json.put("expensesheets", expensesheets); + json.put("materials", materials); + json.put("assigned-quality-forms", assignedQualityForms); HttpURLConnection connection = null; @@ -110,6 +156,7 @@ public class GatheredUsageStats { InputStream inputStream = null; try { + // You can find it in libreplan-business/src/main/resouces String filename = "libreplan.properties"; inputStream = GatheredUsageStats.class.getClassLoader().getResourceAsStream(filename); properties.load(inputStream); @@ -132,7 +179,7 @@ public class GatheredUsageStats { dataOutputStream.flush(); dataOutputStream.close(); - // No needed code, but it is not working without id + // No needed code, but it is not working without it connection.getInputStream(); } catch (MalformedURLException e) { @@ -147,39 +194,65 @@ public class GatheredUsageStats { } } - public void setupNotAutowiredClasses(IUserDAO userDAO, IOrderModel orderModel){ + public void setupNotAutowiredClasses( + IUserDAO userDAO, + IOrderModel orderModel, + IWorkReportModel workReportModel, + IWorkerModel workerModel, + IMachineModel machineModel, + IExpenseSheetModel expenseSheetModel, + IMaterialsModel materialsModel, + IAssignedTaskQualityFormsToOrderElementModel assignedQualityFormModel){ + this.userDAO = userDAO; this.orderModel = orderModel; + this.workReportModel = workReportModel; + this.workerModel = workerModel; + this.machineModel = machineModel; + this.expenseSheetModel = expenseSheetModel; + this.materialsModel = materialsModel; + this.assignedQualityFormModel = assignedQualityFormModel; + myConstructor(); } - public int getJsonObjectVersion() { - return jsonObjectVersion; - } - - public String getId() { - return id; + private Number getUserRows(){ + return userDAO.getRowCount(); } public void setId(String id) { this.id = id; } - public String getVersion() { - return version; - } - - public Number getUsers() { - return users; - } public void setUsers(Number users) { this.users = users; } - public int getProjects() { - return projects; - } public void setProjects(int projects) { this.projects = projects; } + + public void setTimesheets(int timesheets) { + this.timesheets = timesheets; + } + + public void setWorkers(int workers) { + this.workers = workers; + } + + public void setMachines(int machines) { + this.machines = machines; + } + + public void setExpensesheets(int expensesheets) { + this.expensesheets = expensesheets; + } + + public void setMaterials(int materials) { + this.materials = materials; + } + + public void setQualityForms(int qualityForms) { + this.assignedQualityForms = qualityForms; + } } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/materials/MaterialsModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/materials/MaterialsModel.java index 1c86ffe07..7b0110fa6 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/materials/MaterialsModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/materials/MaterialsModel.java @@ -56,11 +56,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.zkoss.ganttz.util.MutableTreeModel; +/** + * @author somebody + * @author Vova Perebykivskiy + */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @OnConcurrentModification(goToPage = "/materials/materials.zul") -public class MaterialsModel extends IntegrationEntityModel implements - IMaterialsModel { +public class MaterialsModel extends IntegrationEntityModel implements IMaterialsModel { @Autowired IMaterialCategoryDAO categoryDAO; @@ -77,8 +80,7 @@ public class MaterialsModel extends IntegrationEntityModel implements @Autowired IMaterialAssignmentDAO materialAssignmentDAO; - MutableTreeModel materialCategories = MutableTreeModel - .create(MaterialCategory.class); + MutableTreeModel materialCategories = MutableTreeModel.create(MaterialCategory.class); private List unitTypes = new ArrayList(); @@ -183,10 +185,9 @@ public class MaterialsModel extends IntegrationEntityModel implements } } - private MaterialCategory findMaterialCategory( - final MaterialCategory category) { + private MaterialCategory findMaterialCategory(final MaterialCategory category) { for (MaterialCategory mc : materialCategories.asList()) { - if (equalsMaterialCategory(mc, category)) { + if ( equalsMaterialCategory(mc, category) ) { return mc; } } @@ -250,24 +251,20 @@ public class MaterialsModel extends IntegrationEntityModel implements } } - private void generateMaterialCodesIfIsNecessary(List categories, - Integer numberOfDigits) { + private void generateMaterialCodesIfIsNecessary(List categories, Integer numberOfDigits) { for (MaterialCategory category: categories) { - if (category.isCodeAutogenerated()) { + if ( category.isCodeAutogenerated() ) { category.generateMaterialCodes(numberOfDigits); } } } - private void checkNoCodeRepeatedAtNewMaterials( - final List categories) throws ValidationException { - List allMaterials = MaterialCategory - .getAllMaterialsWithoutAutogeneratedCodeFrom(categories); + private void checkNoCodeRepeatedAtNewMaterials(final List categories) throws ValidationException { + List allMaterials = MaterialCategory.getAllMaterialsWithoutAutogeneratedCodeFrom(categories); Map byCode = new HashMap(); for (Material each : allMaterials) { - if (byCode.containsKey(each.getCode())) { - throw new ValidationException(sameCodeMessage(each, byCode - .get(each.getCode()))); + if ( byCode.containsKey(each.getCode()) ) { + throw new ValidationException(sameCodeMessage(each, byCode.get(each.getCode()))); } byCode.put(each.getCode(), each); } @@ -295,7 +292,7 @@ public class MaterialsModel extends IntegrationEntityModel implements @Transactional(readOnly = true) public Collection getMaterials() { List result = new ArrayList(); - for (MaterialCategory each: materialCategories.asList()) { + for (MaterialCategory each: getMaterialCategories().asList()) { result.addAll(each.getMaterials()); } return result; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementController.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementController.java index e457e6fc9..b2c87e090 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementController.java @@ -66,11 +66,10 @@ import com.igalia.java.zk.components.customdetailrowcomponent.Detail; * Controller for showing OrderElement assigned task quality forms * @author Susana Montes Pedreira */ -public class AssignedTaskQualityFormsToOrderElementController extends - GenericForwardComposer { +public class AssignedTaskQualityFormsToOrderElementController extends GenericForwardComposer { - private static final org.apache.commons.logging.Log LOG = LogFactory - .getLog(AssignedTaskQualityFormsToOrderElementController.class); + private static final org.apache.commons.logging.Log LOG = + LogFactory.getLog(AssignedTaskQualityFormsToOrderElementController.class); private IMessagesForUser messagesForUser; @@ -123,9 +122,8 @@ public class AssignedTaskQualityFormsToOrderElementController extends } private void setOrderModel(IOrderModel orderModel) { - if (assignedTaskQualityFormsToOrderElementModel != null) { - assignedTaskQualityFormsToOrderElementModel - .setOrderModel(orderModel); + if ( assignedTaskQualityFormsToOrderElementModel != null ) { + assignedTaskQualityFormsToOrderElementModel.setOrderModel(orderModel); } } @@ -229,8 +227,7 @@ public class AssignedTaskQualityFormsToOrderElementController extends } public List getTaskQualityForms() { - return assignedTaskQualityFormsToOrderElementModel - .getTaskQualityForms(); + return assignedTaskQualityFormsToOrderElementModel.getTaskQualityForms(); } public List getNotAssignedQualityForms() { diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementModel.java index 77dd23f3c..1928205a0 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/AssignedTaskQualityFormsToOrderElementModel.java @@ -52,11 +52,11 @@ import org.springframework.transaction.annotation.Transactional; /** * @author Susana Montes Pedreira + * @author Vova Perebykivskiy */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class AssignedTaskQualityFormsToOrderElementModel implements - IAssignedTaskQualityFormsToOrderElementModel { +public class AssignedTaskQualityFormsToOrderElementModel implements IAssignedTaskQualityFormsToOrderElementModel { @Autowired private IOrderElementDAO orderDAO; @@ -101,17 +101,14 @@ public class AssignedTaskQualityFormsToOrderElementModel implements } } - private void initializeTaskQualityForms( - Collection taskQualityForms) { + private void initializeTaskQualityForms(Collection taskQualityForms) { for (TaskQualityForm taskQualityForm : taskQualityForms) { taskQualityForm.getQualityForm().getName(); - initializeTaskQualityFormItems(taskQualityForm - .getTaskQualityFormItems()); + initializeTaskQualityFormItems(taskQualityForm.getTaskQualityFormItems()); } } - public void initializeTaskQualityFormItems( - Collection taskQualityFormItems) { + public void initializeTaskQualityFormItems(Collection taskQualityFormItems) { for (TaskQualityFormItem taskQualityFormItem : taskQualityFormItems) { taskQualityFormItem.getName(); } @@ -120,16 +117,27 @@ public class AssignedTaskQualityFormsToOrderElementModel implements @Override public List getNotAssignedQualityForms() { List result = new ArrayList(); - if (orderElement != null) { - return getlistNotAssignedQualityForms(); + if ( orderElement != null ) { + return getListNotAssignedQualityForms(); } return result; } - private List getlistNotAssignedQualityForms() { + private List getListNotAssignedQualityForms() { List result = new ArrayList(); for (QualityForm qualityForm : orderModel.getQualityForms()) { - if (!isAssigned(qualityForm)) { + if ( !isAssigned(qualityForm) ) { + result.add(qualityForm); + } + } + return result; + } + + @Override + public List getAssignedQualityForms() { + List result = new ArrayList(); + for (QualityForm qualityForm : qualityFormDAO.getAll()) { + if ( isAssigned(qualityForm) ) { result.add(qualityForm); } } @@ -139,7 +147,7 @@ public class AssignedTaskQualityFormsToOrderElementModel implements @Override public List getTaskQualityForms() { List result = new ArrayList(); - if (orderElement != null) { + if ( orderElement != null ) { result.addAll(orderElement.getTaskQualityForms()); } return result; @@ -155,28 +163,37 @@ public class AssignedTaskQualityFormsToOrderElementModel implements orderElement.removeTaskQualityForm(taskQualityForm); } - private AdvanceAssignment getAdvanceAssignment( - TaskQualityForm taskQualityForm) { - AdvanceType advanceType = taskQualityForm.getQualityForm() - .getAdvanceType(); - if (advanceType == null) { + private AdvanceAssignment getAdvanceAssignment(TaskQualityForm taskQualityForm) { + AdvanceType advanceType = taskQualityForm.getQualityForm().getAdvanceType(); + if ( advanceType == null ) { return null; } else { advanceTypeDAO.reattach(advanceType); - return taskQualityForm.getOrderElement() - .getDirectAdvanceAssignmentByType(advanceType); + return taskQualityForm.getOrderElement().getDirectAdvanceAssignmentByType(advanceType); } } @Override public boolean isAssigned(QualityForm qualityForm) { - for (TaskQualityForm taskQualityForm : orderElement - .getTaskQualityForms()) { - if (qualityForm.equals(taskQualityForm.getQualityForm())) { - return true; + // orderDAO used for gathered data to be sent to LibrePlan server + // In general case orderElement will be not null and only that part of code will be triggered + + if ( orderElement != null ){ + for (TaskQualityForm taskQualityForm : orderElement.getTaskQualityForms()) { + if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) { + return true; + } + } + } else { + for (OrderElement currentElement : orderDAO.getAll()) { + for ( TaskQualityForm taskQualityForm : currentElement.getTaskQualityForms() ) + if ( qualityForm.equals(taskQualityForm.getQualityForm()) ) { + return true; + } } } + return false; } @@ -185,32 +202,28 @@ public class AssignedTaskQualityFormsToOrderElementModel implements this.orderModel = orderModel; } - public boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, - TaskQualityFormItem item) { - if ((taskQualityForm == null) || ((item == null))) { + public boolean isDisabledPassedItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { + if ( (taskQualityForm == null) || ((item == null)) ) { return true; } - if (!taskQualityForm.isByItems()) { - return (!(item.getPassed() || taskQualityForm - .isPassedPreviousItem(item))); + if ( !taskQualityForm.isByItems() ) { + return (!(item.getPassed() || taskQualityForm.isPassedPreviousItem(item))); } return false; } - public boolean isDisabledDateItem(TaskQualityForm taskQualityForm, - TaskQualityFormItem item) { - if ((taskQualityForm == null) || ((item == null))) { + public boolean isDisabledDateItem(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { + if ( (taskQualityForm == null) || ((item == null)) ) { return true; } return (!taskQualityForm.isByItems() && (!item.getPassed())); } - public boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, - TaskQualityFormItem item) { - if ((taskQualityForm == null) || ((item == null))) { + public boolean isCorrectConsecutiveDate(TaskQualityForm taskQualityForm, TaskQualityFormItem item) { + if ( (taskQualityForm == null) || ((item == null)) ) { return true; } - if (taskQualityForm.isByItems()) { + if ( taskQualityForm.isByItems() ) { return true; } return (taskQualityForm.isCorrectConsecutiveDate(item)); @@ -288,50 +301,40 @@ public class AssignedTaskQualityFormsToOrderElementModel implements public void addAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm) throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException { - AdvanceType advanceType = taskQualityForm.getQualityForm() - .getAdvanceType(); - advanceTypeDAO.reattach(advanceType); - AdvanceAssignment advanceAssignment = taskQualityForm.getOrderElement() - .getDirectAdvanceAssignmentByType(advanceType); - if (advanceAssignment == null) { - DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment - .create(false, new BigDecimal(100)); + AdvanceType advanceType = taskQualityForm.getQualityForm().getAdvanceType(); + advanceTypeDAO.reattach(advanceType); + + AdvanceAssignment advanceAssignment = + taskQualityForm.getOrderElement().getDirectAdvanceAssignmentByType(advanceType); + + if ( advanceAssignment == null ) { + DirectAdvanceAssignment newAdvanceAssignment = DirectAdvanceAssignment.create(false, new BigDecimal(100)); newAdvanceAssignment.setAdvanceType(advanceType); - taskQualityForm.getOrderElement().addAdvanceAssignment( - newAdvanceAssignment); + taskQualityForm.getOrderElement().addAdvanceAssignment(newAdvanceAssignment); addAdvanceMeasurements(taskQualityForm, newAdvanceAssignment); } } - private void addAdvanceMeasurements(TaskQualityForm taskQualityForm, - DirectAdvanceAssignment newAdvanceAssignment) { - for (TaskQualityFormItem taskQualityFormItem : taskQualityForm - .getTaskQualityFormItems()) { - if (taskQualityFormItem.getPassed() - && (taskQualityFormItem.getDate() != null)) { - LocalDate date = LocalDate - .fromDateFields(taskQualityFormItem.getDate()); + private void addAdvanceMeasurements(TaskQualityForm taskQualityForm, DirectAdvanceAssignment newAdvanceAssignment) { + for (TaskQualityFormItem taskQualityFormItem : taskQualityForm.getTaskQualityFormItems()) { + if ( taskQualityFormItem.getPassed() && (taskQualityFormItem.getDate() != null) ) { + LocalDate date = LocalDate.fromDateFields(taskQualityFormItem.getDate()); BigDecimal value = taskQualityFormItem.getPercentage(); - newAdvanceAssignment - .addAdvanceMeasurements(AdvanceMeasurement - .create(date, value)); + newAdvanceAssignment.addAdvanceMeasurements(AdvanceMeasurement.create(date, value)); } } } @Override @Transactional(readOnly = true) - public void removeAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm) - throws ValidationException { - AdvanceAssignment advanceAssignment = this - .getAdvanceAssignment(taskQualityForm); - if (advanceAssignment != null) { - if (advanceAssignment.getReportGlobalAdvance()) { + public void removeAdvanceAssignmentIfNeeded(TaskQualityForm taskQualityForm) throws ValidationException { + AdvanceAssignment advanceAssignment = this.getAdvanceAssignment(taskQualityForm); + if ( advanceAssignment != null ) { + if ( advanceAssignment.getReportGlobalAdvance() ) { showMessageDeleteSpread(); } else { - taskQualityForm.getOrderElement().removeAdvanceAssignment( - advanceAssignment); + taskQualityForm.getOrderElement().removeAdvanceAssignment(advanceAssignment); } } } @@ -343,12 +346,13 @@ public class AssignedTaskQualityFormsToOrderElementModel implements @Override public void updateAdvancesIfNeeded() { - if (orderElement != null) { + if ( orderElement != null ) { for (TaskQualityForm taskQualityForm : getTaskQualityForms()) { - if (taskQualityForm.isReportAdvance()) { - DirectAdvanceAssignment advanceAssignment = orderElement - .getAdvanceAssignmentByType(taskQualityForm - .getQualityForm().getAdvanceType()); + if ( taskQualityForm.isReportAdvance() ) { + + DirectAdvanceAssignment advanceAssignment = + orderElement.getAdvanceAssignmentByType(taskQualityForm.getQualityForm().getAdvanceType()); + advanceAssignment.clearAdvanceMeasurements(); addAdvanceMeasurements(taskQualityForm, advanceAssignment); } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/IAssignedTaskQualityFormsToOrderElementModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/IAssignedTaskQualityFormsToOrderElementModel.java index 391399d39..fc443c7c7 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/IAssignedTaskQualityFormsToOrderElementModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/IAssignedTaskQualityFormsToOrderElementModel.java @@ -33,6 +33,7 @@ import org.libreplan.business.qualityforms.entities.TaskQualityFormItem; /** * @author Susana Montes Pedreira + * @author Vova Perebykivskiy */ public interface IAssignedTaskQualityFormsToOrderElementModel { @@ -62,6 +63,11 @@ public interface IAssignedTaskQualityFormsToOrderElementModel { */ List getNotAssignedQualityForms(); + /** + * Returns all the allocated {@link QualityForm} needed for gathering usage statistics. + */ + List getAssignedQualityForms(); + /** * Returns {@link OrderElement} * @return diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java index d88a50627..f78420b4d 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderCRUDController.java @@ -127,6 +127,7 @@ import org.zkoss.zul.api.Window; * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro * @author Manuel Rego Casasnovas + * @author Vova Perebykivskiy */ @org.springframework.stereotype.Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -134,8 +135,7 @@ public class OrderCRUDController extends GenericForwardComposer { private static final String DEFAULT_TAB = "tabOrderElements"; - private static final org.apache.commons.logging.Log LOG = LogFactory - .getLog(OrderCRUDController.class); + private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(OrderCRUDController.class); @Autowired private IOrderModel orderModel; @@ -698,16 +698,17 @@ public class OrderCRUDController extends GenericForwardComposer { private AssignedTaskQualityFormsToOrderElementController assignedTaskQualityFormController; public void setupAssignedTaskQualityFormsToOrderElementController() { - if (!confirmLastTab()) { + if ( !confirmLastTab() ) { return; } setCurrentTab(); - Component orderElementTaskQualityForms = editWindow - .getFellowIfAny("orderElementTaskQualityForms"); - if (assignedTaskQualityFormController == null) { + Component orderElementTaskQualityForms = editWindow.getFellowIfAny("orderElementTaskQualityForms"); + if ( assignedTaskQualityFormController == null ) { + assignedTaskQualityFormController = (AssignedTaskQualityFormsToOrderElementController) orderElementTaskQualityForms .getVariable("assignedTaskQualityFormsController", true); + final IOrderElementModel orderElementModel = getOrderElementModel(); assignedTaskQualityFormController.openWindow(orderElementModel); } else { @@ -1018,9 +1019,8 @@ public class OrderCRUDController extends GenericForwardComposer { private void remove(Order order) { boolean hasImputedExpenseSheets = orderModel.hasImputedExpenseSheetsThisOrAnyOfItsChildren(order); - if (hasImputedExpenseSheets) { - messagesForUser - .showMessage( + if ( hasImputedExpenseSheets ) { + messagesForUser.showMessage( Level.ERROR, _("You can not remove the project \"{0}\" because this one has imputed expense sheets.", order.getName())); @@ -1028,22 +1028,19 @@ public class OrderCRUDController extends GenericForwardComposer { } boolean alreadyInUse = orderModel.isAlreadyInUseAndIsOnlyInCurrentScenario(order); - if (alreadyInUse) { - messagesForUser - .showMessage( + if ( alreadyInUse ) { + messagesForUser.showMessage( Level.ERROR, - _( - "You can not remove the project \"{0}\" because it has time tracked at some of its tasks", + _("You can not remove the project \"{0}\" because it has time tracked at some of its tasks", order.getName())); } else { - if (!StringUtils.isBlank(order.getExternalCode())) { + if ( !StringUtils.isBlank(order.getExternalCode()) ) { try { - if (Messagebox - .show( - _("This project is a subcontracted project. If you delete it, you won't be able to report progress anymore. Are you sure?"), - _("Confirm"), Messagebox.OK - | Messagebox.CANCEL, - Messagebox.QUESTION) == Messagebox.CANCEL) { + if ( Messagebox.show( + _("This project is a subcontracted project. If you delete it, " + + "you won't be able to report progress anymore. Are you sure?"), + _("Confirm"), + Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.CANCEL ) { return; } } catch (InterruptedException e) { @@ -1053,20 +1050,22 @@ public class OrderCRUDController extends GenericForwardComposer { orderModel.remove(order); Util.reloadBindings(self); - messagesForUser.showMessage(Level.INFO, _("Removed {0}", order - .getName())); + + messagesForUser.clearMessages(); + messagesForUser.showMessage(Level.INFO, _("Removed {0}", order.getName())); } } public void schedule(Order order) { orderModel.useSchedulingDataForCurrentScenario(order); - if(orderModel.userCanRead(order, SecurityUtils.getSessionUserLoginName())) { - if (order.isScheduled()) { + if( orderModel.userCanRead(order, SecurityUtils.getSessionUserLoginName()) ) { + if ( order.isScheduled() ) { planningControllerEntryPoints.goToScheduleOf(order); showCreateButtons(false); } else { try { - Messagebox.show(_("The project has no scheduled elements"), + Messagebox.show( + _("The project has no scheduled elements"), _("Information"), Messagebox.OK, Messagebox.INFORMATION); } catch (InterruptedException e) { throw new RuntimeException(e); @@ -1075,7 +1074,8 @@ public class OrderCRUDController extends GenericForwardComposer { } else { try { - Messagebox.show(_("You don't have read access to this project"), + Messagebox.show( + _("You don't have read access to this project"), _("Information"), Messagebox.OK, Messagebox.INFORMATION); } catch (InterruptedException e) { throw new RuntimeException(e); diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderModel.java index b875269f6..33928398a 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/orders/OrderModel.java @@ -185,7 +185,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel { private LabelsOnConversation labelsOnConversation; private LabelsOnConversation getLabelsOnConversation() { - if (labelsOnConversation == null) { + if ( labelsOnConversation == null ) { labelsOnConversation = new LabelsOnConversation(labelDAO); } return labelsOnConversation; @@ -194,9 +194,8 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel { private QualityFormsOnConversation qualityFormsOnConversation; private QualityFormsOnConversation getQualityFormsOnConversation() { - if (qualityFormsOnConversation == null) { - qualityFormsOnConversation = new QualityFormsOnConversation( - qualityFormDAO); + if ( qualityFormsOnConversation == null ) { + qualityFormsOnConversation = new QualityFormsOnConversation(qualityFormDAO); } return qualityFormsOnConversation; } diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java index e73dcfb8a..cf628ce76 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/tabs/MultipleTabsPlannerController.java @@ -43,9 +43,12 @@ import org.libreplan.web.common.entrypoints.EntryPointsHandler; import org.libreplan.web.common.entrypoints.URLHandlerRegistry; import org.libreplan.web.dashboard.DashboardController; import org.libreplan.web.dashboard.DashboardControllerGlobal; +import org.libreplan.web.expensesheet.IExpenseSheetModel; import org.libreplan.web.limitingresources.LimitingResourcesController; import org.libreplan.web.logs.LogsController; +import org.libreplan.web.materials.IMaterialsModel; import org.libreplan.web.montecarlo.MonteCarloController; +import org.libreplan.web.orders.IAssignedTaskQualityFormsToOrderElementModel; import org.libreplan.web.orders.IOrderModel; import org.libreplan.web.orders.OrderCRUDController; import org.libreplan.web.planner.allocation.AdvancedAllocationController.IBack; @@ -55,7 +58,10 @@ import org.libreplan.web.planner.order.OrderPlanningController; import org.libreplan.web.planner.order.PlanningStateCreator; import org.libreplan.web.planner.tabs.Mode.ModeTypeChangedListener; import org.libreplan.web.resourceload.ResourceLoadController; +import org.libreplan.web.resources.machine.IMachineModel; +import org.libreplan.web.resources.worker.IWorkerModel; import org.libreplan.web.security.SecurityUtils; +import org.libreplan.web.workreports.IWorkReportModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; @@ -88,8 +94,7 @@ import org.zkoss.zk.ui.util.Composer; */ @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class MultipleTabsPlannerController implements Composer, - IGlobalViewEntryPoints { +public class MultipleTabsPlannerController implements Composer, IGlobalViewEntryPoints { public static String WELCOME_URL = "-- no URL provided --"; @@ -102,7 +107,7 @@ public class MultipleTabsPlannerController implements Composer, @Override public void show() { - if (feedback) { + if ( feedback ) { showWithFeedback(); } else { showWithoutFeedback(); @@ -152,6 +157,8 @@ public class MultipleTabsPlannerController implements Composer, @Autowired private OrderCRUDController orderCRUDController; + + @Autowired private PlanningStateCreator planningStateCreator; @@ -220,14 +227,30 @@ public class MultipleTabsPlannerController implements Composer, @Autowired private URLHandlerRegistry registry; - // Cannot Autowire it in GatheredUsageStats class @Autowired private IUserDAO userDAO; @Autowired private IOrderModel orderModel; - private boolean isGatheredStatsAlreadySent = false; + @Autowired + private IWorkReportModel workReportModel; + + @Autowired + private IWorkerModel workerModel; + + @Autowired + private IMachineModel machineModel; + + @Autowired + private IExpenseSheetModel expenseSheetModel; + + @Autowired + private IMaterialsModel materialsModel; + + @Autowired + private IAssignedTaskQualityFormsToOrderElementModel assignedQualityFormsModel; + private TabsConfiguration buildTabsConfiguration(final Desktop desktop) { @@ -238,17 +261,19 @@ public class MultipleTabsPlannerController implements Composer, @Override public void typeChanged(ModeType oldType, ModeType newType) { switch (newType) { + case GLOBAL: ConfirmCloseUtil.resetConfirmClose(); break; + case ORDER: - if (SecurityUtils.loggedUserCanWrite(mode.getOrder())) { - ConfirmCloseUtil - .setConfirmClose( - desktop, - _("You are about to leave the planning editing. Unsaved changes will be lost!")); + if ( SecurityUtils.loggedUserCanWrite(mode.getOrder()) ) { + ConfirmCloseUtil.setConfirmClose( + desktop, + _("You are about to leave the planning editing. Unsaved changes will be lost!")); } break; + default: break; } @@ -510,12 +535,20 @@ public class MultipleTabsPlannerController implements Composer, } } - if ( !isGatheredStatsAlreadySent && configurationDAO.getConfiguration().isAllowToGatherUsageStatsEnabled() ){ - GatheredUsageStats gatheredUsageStats = new GatheredUsageStats(); - gatheredUsageStats.setupNotAutowiredClasses(userDAO, orderModel); - gatheredUsageStats.sendGatheredUsageStatsToServer(); - isGatheredStatsAlreadySent = true; - } + // Send data to server + if ( !SecurityUtils.isGatheredStatsAlreadySent && + configurationDAO.getConfiguration().isAllowToGatherUsageStatsEnabled() ) + sendDataToServer(); + } + + private void sendDataToServer(){ + GatheredUsageStats gatheredUsageStats = new GatheredUsageStats(); + + gatheredUsageStats.setupNotAutowiredClasses(userDAO, orderModel, workReportModel, workerModel, machineModel, + expenseSheetModel, materialsModel, assignedQualityFormsModel); + + gatheredUsageStats.sendGatheredUsageStatsToServer(); + SecurityUtils.isGatheredStatsAlreadySent = true; } private TabsRegistry getTabsRegistry() { diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/qualityforms/QualityFormModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/qualityforms/QualityFormModel.java index ea0c81c3c..11d2b53a5 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/qualityforms/QualityFormModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/qualityforms/QualityFormModel.java @@ -135,7 +135,7 @@ public class QualityFormModel implements IQualityFormModel { public List getQualityFormItems() { // Safe copy List items = new ArrayList(); - if (qualityForm != null) { + if ( qualityForm != null ) { items.addAll(qualityForm.getQualityFormItems()); } return items; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerModel.java b/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerModel.java index aa82fdd70..3857249d8 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerModel.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/resources/worker/WorkerModel.java @@ -50,7 +50,6 @@ import org.libreplan.business.planner.daos.IResourceAllocationDAO; import org.libreplan.business.resources.daos.ICriterionDAO; import org.libreplan.business.resources.daos.IResourceDAO; import org.libreplan.business.resources.daos.IWorkerDAO; -import org.libreplan.business.resources.daos.WorkerDAO; import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.resources.entities.CriterionSatisfaction; import org.libreplan.business.resources.entities.CriterionWithItsType; @@ -90,8 +89,7 @@ import org.springframework.transaction.annotation.Transactional; @OnConcurrentModification(goToPage = "/resources/worker/worker.zul") public class WorkerModel extends IntegrationEntityModel implements IWorkerModel { - private static final org.apache.commons.logging.Log LOG = LogFactory - .getLog(WorkerModel.class); + private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(WorkerModel.class); @Autowired private IResourceDAO resourceDAO; @@ -99,9 +97,6 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel @Autowired private IBaseCalendarDAO baseCalendarDAO; - @Autowired - private IWorkerDAO workerDAO; - private final ICriterionType[] laboralRelatedTypes = { PredefinedCriterionTypes.LOCATION, PredefinedCriterionTypes.CATEGORY, PredefinedCriterionTypes.SKILL }; diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/security/SecurityUtils.java b/libreplan-webapp/src/main/java/org/libreplan/web/security/SecurityUtils.java index f6a7377a4..15ee90c01 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/security/SecurityUtils.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/security/SecurityUtils.java @@ -46,9 +46,13 @@ import org.zkoss.zk.ui.Executions; * @author Fernando Bellas Permuy * @author Jacobo Aragunde Perez * @author Cristina Alvarino Perez + * @author Vova Perebykivskiy */ public final class SecurityUtils { + // Related to the data that is sending to LibrePlan server + public static boolean isGatheredStatsAlreadySent = false; + private SecurityUtils() {} public final static boolean isUserInRole(UserRole role) {