ItEr37S13CUAsignacionMateriaisAPedidoItEr36S15: Assign Materials to Order
This commit is contained in:
parent
b4e81de660
commit
01249ee2a9
19 changed files with 1457 additions and 4 deletions
|
|
@ -328,4 +328,33 @@ public class MutableTreeModel<T> extends AbstractTreeModel {
|
|||
return getChildCount(node) > 0;
|
||||
}
|
||||
|
||||
public boolean contains(T parent, T child) {
|
||||
Node<T> parentNode = find(parent);
|
||||
Node<T> childNode = find(child);
|
||||
|
||||
if (parentNode != null && (childNode != null && childNode.getParent() != null)) {
|
||||
return childNode.getParent().equals(parentNode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<T> asList() {
|
||||
List<T> result = new ArrayList<T>();
|
||||
asList(getRoot(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void asList(T root, List<T> result) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
for (int i = 0; i < getChildCount(root); i++) {
|
||||
final T child = getChild(root, i);
|
||||
list.add(child);
|
||||
result.add(child);
|
||||
}
|
||||
|
||||
for (T each: list) {
|
||||
asList(each, result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,6 +440,29 @@ public class MutableTreeModelTest {
|
|||
assertThat(model.getChild(model.getRoot(), 1), equalTo(prueba2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void treeParentContainsChild() {
|
||||
final MutableTreeModel<Prueba> model = MutableTreeModel
|
||||
.create(Prueba.class);
|
||||
|
||||
Prueba parent = new Prueba();
|
||||
model.addToRoot(parent);
|
||||
Prueba child = new Prueba();
|
||||
model.add(parent, child);
|
||||
assertTrue(model.contains(parent, child));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void treeParentDoesNotContainChild() {
|
||||
final MutableTreeModel<Prueba> model = MutableTreeModel
|
||||
.create(Prueba.class);
|
||||
|
||||
Prueba parent = new Prueba();
|
||||
model.addToRoot(parent);
|
||||
Prueba child = new Prueba();
|
||||
assertFalse(model.contains(parent, child));
|
||||
}
|
||||
|
||||
private void checkIsValid(TreeDataEvent event, int type,
|
||||
Prueba expectedParent, int expectedPosition) {
|
||||
checkIsValid(event, type, expectedParent, expectedPosition,
|
||||
|
|
@ -461,4 +484,5 @@ public class MutableTreeModelTest {
|
|||
}
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,50 @@
|
|||
package org.navalplanner.business.materials.daos;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.materials.entities.Material;
|
||||
import org.navalplanner.business.materials.entities.MaterialCategory;
|
||||
|
||||
/**
|
||||
* Interface IMaterialDAO
|
||||
*
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
public interface IMaterialDAO extends IGenericDAO<Material, Long> {
|
||||
|
||||
/**
|
||||
* Searches {@link Material} by code and description (ilike matching) within
|
||||
* categories
|
||||
*
|
||||
* @param text
|
||||
* @param categories
|
||||
* @return
|
||||
*/
|
||||
List<Material> findMaterialsInCategories(String text,
|
||||
Set<MaterialCategory> categories);
|
||||
|
||||
/**
|
||||
* Searches {@link Material} by code and description (ilike matching) within
|
||||
* category and its subcategories
|
||||
*
|
||||
* @param text
|
||||
* @param materialCategory
|
||||
* @return
|
||||
*/
|
||||
List<Material> findMaterialsInCategoryAndSubCategories(String text,
|
||||
MaterialCategory materialCategory);
|
||||
|
||||
List<Material> getAll();
|
||||
|
||||
/**
|
||||
* Returns all subcategories for materialCategory
|
||||
*
|
||||
* @param materialCategory
|
||||
* @return
|
||||
*/
|
||||
Set<MaterialCategory> getAllSubcategories(MaterialCategory materialCategory);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,15 @@
|
|||
|
||||
package org.navalplanner.business.materials.daos;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.materials.entities.Material;
|
||||
import org.navalplanner.business.materials.entities.MaterialCategory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
|
@ -32,6 +37,7 @@ import org.springframework.stereotype.Repository;
|
|||
* DAO for {@link Material}
|
||||
*
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
|
|
@ -43,4 +49,44 @@ public class MaterialDAO extends GenericDAOHibernate<Material, Long> implements
|
|||
return list(Material.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Material> findMaterialsInCategoryAndSubCategories(String text,
|
||||
MaterialCategory materialCategory) {
|
||||
Set<MaterialCategory> materialCategories = new HashSet<MaterialCategory>();
|
||||
if (materialCategory != null) {
|
||||
materialCategories.add(materialCategory);
|
||||
materialCategories.addAll(getAllSubcategories(materialCategory));
|
||||
}
|
||||
return findMaterialsInCategories(text, materialCategories);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MaterialCategory> getAllSubcategories(MaterialCategory materialCategory) {
|
||||
Set<MaterialCategory> result = new HashSet<MaterialCategory>();
|
||||
getAllSubcategories(result, materialCategory.getSubcategories());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getAllSubcategories(Set<MaterialCategory> materialCategories, Set<MaterialCategory> subcategories) {
|
||||
for (MaterialCategory each: subcategories) {
|
||||
materialCategories.add(each);
|
||||
getAllSubcategories(materialCategories, each.getSubcategories());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<Material> findMaterialsInCategories(String text,
|
||||
Set<MaterialCategory> categories) {
|
||||
Criteria criteria = this.getSession().createCriteria(Material.class);
|
||||
|
||||
text = "%" + text + "%";
|
||||
criteria.add(Restrictions.or(Restrictions.ilike("code", text), Restrictions.eq("description", text)));
|
||||
criteria.add(Restrictions.eq("disabled", false));
|
||||
if (categories != null && !categories.isEmpty()) {
|
||||
criteria.add(Restrictions.in("category", categories));
|
||||
}
|
||||
return criteria.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class Material extends BaseEntity implements Comparable {
|
|||
|
||||
private String description;
|
||||
|
||||
private BigDecimal defaultUnitPrice;
|
||||
private BigDecimal defaultUnitPrice = new BigDecimal(0);
|
||||
|
||||
private UnitTypeEnum unitType;
|
||||
|
||||
|
|
@ -113,7 +113,6 @@ public class Material extends BaseEntity implements Comparable {
|
|||
@Override
|
||||
public int compareTo(Object arg0) {
|
||||
final Material material = (Material) arg0;
|
||||
|
||||
return code.compareTo(material.getCode());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* This file is part of ###PROJECT_NAME###
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* 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.navalplanner.business.materials.entities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class MaterialAssignment extends BaseEntity implements Comparable {
|
||||
|
||||
Material material;
|
||||
|
||||
double units = 0;
|
||||
|
||||
BigDecimal unitPrice = new BigDecimal(0);
|
||||
|
||||
Date estimatedAvailability;
|
||||
|
||||
MaterialStatusEnum status = MaterialStatusEnum.PENDING;
|
||||
|
||||
OrderElement orderElement;
|
||||
|
||||
public static MaterialAssignment create() {
|
||||
return BaseEntity.create(new MaterialAssignment());
|
||||
}
|
||||
|
||||
protected MaterialAssignment() {
|
||||
|
||||
}
|
||||
|
||||
public static MaterialAssignment create(Material material) {
|
||||
MaterialAssignment materialAssignment = create();
|
||||
materialAssignment.setUnitPrice(material.getDefaultUnitPrice());
|
||||
materialAssignment.setMaterial(material);
|
||||
return materialAssignment;
|
||||
}
|
||||
|
||||
public static MaterialAssignment create(MaterialAssignment materialAssignment) {
|
||||
MaterialAssignment result = create();
|
||||
result.setMaterial(materialAssignment.getMaterial());
|
||||
result.setUnits(materialAssignment.getUnits());
|
||||
result.setUnitPrice(materialAssignment.getUnitPrice());
|
||||
result.setEstimatedAvailability(materialAssignment.getEstimatedAvailability());
|
||||
result.setStatus(materialAssignment.getStatus());
|
||||
return result;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public void setMaterial(Material material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public double getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
public void setUnits(double units) {
|
||||
this.units = units;
|
||||
}
|
||||
|
||||
public BigDecimal getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(BigDecimal unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalPrice() {
|
||||
BigDecimal result = new BigDecimal(getUnits());
|
||||
return result.multiply(getUnitPrice());
|
||||
}
|
||||
|
||||
public void setTotalPrice(BigDecimal totalPrice) {
|
||||
BigDecimal unitPrice = totalPrice;
|
||||
unitPrice = unitPrice.divide(new BigDecimal(units), 3, RoundingMode.HALF_UP);
|
||||
setUnitPrice(unitPrice);
|
||||
}
|
||||
|
||||
public Date getEstimatedAvailability() {
|
||||
return estimatedAvailability;
|
||||
}
|
||||
|
||||
public void setEstimatedAvailability(Date estimatedAvailability) {
|
||||
this.estimatedAvailability = estimatedAvailability;
|
||||
}
|
||||
|
||||
public MaterialStatusEnum getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(MaterialStatusEnum status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public OrderElement getOrderElement() {
|
||||
return orderElement;
|
||||
}
|
||||
|
||||
public void setOrderElement(OrderElement orderElement) {
|
||||
this.orderElement = orderElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object arg0) {
|
||||
final MaterialAssignment materialAssignment = (MaterialAssignment) arg0;
|
||||
return materialAssignment.getMaterial().compareTo(getMaterial());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of ###PROJECT_NAME###
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* 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.navalplanner.business.materials.entities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public enum MaterialStatusEnum {
|
||||
RECEIVED,
|
||||
PENDING,
|
||||
ORDERED,
|
||||
PROCESSING,
|
||||
CANCELED
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ import org.navalplanner.business.advance.exceptions.DuplicateAdvanceAssignmentFo
|
|||
import org.navalplanner.business.advance.exceptions.DuplicateValueTrueReportGlobalAdvanceException;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.labels.entities.Label;
|
||||
import org.navalplanner.business.materials.entities.MaterialAssignment;
|
||||
import org.navalplanner.business.orders.entities.SchedulingState.ITypeChangedListener;
|
||||
import org.navalplanner.business.orders.entities.SchedulingState.Type;
|
||||
import org.navalplanner.business.orders.entities.TaskSource.TaskSourceSynchronization;
|
||||
|
|
@ -68,6 +69,8 @@ public abstract class OrderElement extends BaseEntity {
|
|||
|
||||
protected Set<DirectAdvanceAssignment> directAdvanceAssignments = new HashSet<DirectAdvanceAssignment>();
|
||||
|
||||
protected Set<MaterialAssignment> materialAssignments = new HashSet<MaterialAssignment>();
|
||||
|
||||
private Set<Label> labels = new HashSet<Label>();
|
||||
|
||||
private String code;
|
||||
|
|
@ -262,6 +265,13 @@ public abstract class OrderElement extends BaseEntity {
|
|||
|
||||
public void setInitDate(Date initDate) {
|
||||
this.initDate = initDate;
|
||||
updateMaterialAssigmentsEstimatedAvailability(this.initDate);
|
||||
}
|
||||
|
||||
private void updateMaterialAssigmentsEstimatedAvailability(Date estimatedAvailability) {
|
||||
for (MaterialAssignment each: materialAssignments) {
|
||||
each.setEstimatedAvailability(estimatedAvailability);
|
||||
}
|
||||
}
|
||||
|
||||
public Date getDeadline() {
|
||||
|
|
@ -644,4 +654,38 @@ public abstract class OrderElement extends BaseEntity {
|
|||
result.add(taskSource);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<MaterialAssignment> getMaterialAssignments() {
|
||||
return Collections.unmodifiableSet(materialAssignments);
|
||||
}
|
||||
|
||||
public void addMaterialAssignment(MaterialAssignment materialAssignment) {
|
||||
materialAssignments.add(materialAssignment);
|
||||
materialAssignment.setOrderElement(this);
|
||||
}
|
||||
|
||||
public void removeMaterialAssignment(MaterialAssignment materialAssignment) {
|
||||
materialAssignments.remove(materialAssignment);
|
||||
}
|
||||
|
||||
public double getTotalMaterialAssigmentUnits() {
|
||||
double result = 0;
|
||||
|
||||
final Set<MaterialAssignment> materialAssigments = getMaterialAssignments();
|
||||
for (MaterialAssignment each: materialAssigments) {
|
||||
result += each.getUnits();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalMaterialAssigmentPrice() {
|
||||
BigDecimal result = new BigDecimal(0);
|
||||
|
||||
final Set<MaterialAssignment> materialAssigments = getMaterialAssignments();
|
||||
for (MaterialAssignment each: materialAssigments) {
|
||||
result = result.add(each.getTotalPrice());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,4 +54,31 @@
|
|||
|
||||
</class>
|
||||
|
||||
<!-- MaterialAssignment -->
|
||||
<class name="MaterialAssignment" table="MATERIAL_ASSIGMENT">
|
||||
<id name="id" type="long" access="property">
|
||||
<generator class="hilo">
|
||||
<param name="max_lo">100</param>
|
||||
</generator>
|
||||
</id>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<property name="units" />
|
||||
|
||||
<property name="unitPrice" column="UNIT_PRICE" />
|
||||
|
||||
<property name="estimatedAvailability" column="ESTIMATED_AVAILABILITY" />
|
||||
|
||||
<property name="status">
|
||||
<type name="org.hibernate.type.EnumType">
|
||||
<param name="enumClass">org.navalplanner.business.materials.entities.MaterialStatusEnum</param>
|
||||
</type>
|
||||
</property>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="ORDER_ELEMENT_ID" />
|
||||
|
||||
<many-to-one name="material" class="Material" column="MATERIAL_ID" />
|
||||
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping package="org.navalplanner.business.orders.entities">
|
||||
<hibernate-mapping package="org.navalplanner.business.orders.entities" default-access="field">
|
||||
<class name="OrderElement" abstract="true">
|
||||
<id name="id" access="property" type="long">
|
||||
<generator class="hilo" >
|
||||
|
|
@ -37,6 +37,11 @@
|
|||
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement"/>
|
||||
</set>
|
||||
|
||||
<set name="materialAssignments" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.materials.entities.MaterialAssignment" />
|
||||
</set>
|
||||
|
||||
<!-- Inverse navigation from OrderElement to OrderLineGroup -->
|
||||
<many-to-one name="parent" access="field" cascade="all"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
* This file is part of ###PROJECT_NAME###
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* 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.navalplanner.web.orders;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.navalplanner.business.materials.entities.Material;
|
||||
import org.navalplanner.business.materials.entities.MaterialAssignment;
|
||||
import org.navalplanner.business.materials.entities.MaterialCategory;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.web.common.Util;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
import org.zkoss.zk.ui.SuspendNotAllowedException;
|
||||
import org.zkoss.zk.ui.util.GenericForwardComposer;
|
||||
import org.zkoss.zul.Doublebox;
|
||||
import org.zkoss.zul.Grid;
|
||||
import org.zkoss.zul.Label;
|
||||
import org.zkoss.zul.Listbox;
|
||||
import org.zkoss.zul.Listitem;
|
||||
import org.zkoss.zul.Messagebox;
|
||||
import org.zkoss.zul.Row;
|
||||
import org.zkoss.zul.SimpleListModel;
|
||||
import org.zkoss.zul.Tab;
|
||||
import org.zkoss.zul.Tree;
|
||||
import org.zkoss.zul.TreeModel;
|
||||
import org.zkoss.zul.Treecell;
|
||||
import org.zkoss.zul.Treeitem;
|
||||
import org.zkoss.zul.TreeitemRenderer;
|
||||
import org.zkoss.zul.Treerow;
|
||||
import org.zkoss.zul.api.Textbox;
|
||||
import org.zkoss.zul.impl.MessageboxDlg;
|
||||
|
||||
/**
|
||||
* Controller for showing {@link OrderElement} assigned {@link Material}
|
||||
*
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class AssignedMaterialsToOrderElementController extends
|
||||
GenericForwardComposer {
|
||||
|
||||
private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(AssignedMaterialsToOrderElementController.class);
|
||||
|
||||
private IAssignedMaterialsToOrderElementModel assignedMaterialsToOrderElementModel;
|
||||
|
||||
private Tree categoriesTree;
|
||||
|
||||
private Tree allCategoriesTree;
|
||||
|
||||
private Grid gridMaterials;
|
||||
|
||||
private Listbox lbFoundMaterials;
|
||||
|
||||
private Textbox txtSearchMaterial;
|
||||
|
||||
private Tab tbAssignedMaterials;
|
||||
|
||||
@Override
|
||||
public void doAfterCompose(Component comp) throws Exception {
|
||||
super.doAfterCompose(comp);
|
||||
comp.setVariable("assignedMaterialsController", this, true);
|
||||
}
|
||||
|
||||
public void openWindow(IOrderElementModel orderElementModel) {
|
||||
assignedMaterialsToOrderElementModel.initEdit(orderElementModel);
|
||||
prepareCategoriesTree();
|
||||
prepareAllCategoriesTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay initialization of categories tree till user clicks on Materials tab
|
||||
*
|
||||
* Initializing model and renderer properties directly in ZUL resulted in calling the renderer
|
||||
* more times than actually needed, resulting in noticeable lack of performance
|
||||
*/
|
||||
private void prepareCategoriesTree() {
|
||||
if (categoriesTree.getTreeitemRenderer() == null) {
|
||||
categoriesTree.setTreeitemRenderer(getMaterialCategoryWithUnitsAndPriceRenderer());
|
||||
}
|
||||
categoriesTree.setModel(getMaterialCategories());
|
||||
}
|
||||
|
||||
public TreeModel getMaterialCategories() {
|
||||
return assignedMaterialsToOrderElementModel.getMaterialCategories();
|
||||
}
|
||||
|
||||
private void prepareAllCategoriesTree() {
|
||||
if (allCategoriesTree.getTreeitemRenderer() == null) {
|
||||
allCategoriesTree.setTreeitemRenderer(getMaterialCategoryRenderer());
|
||||
}
|
||||
allCategoriesTree.setModel(getAllMaterialCategories());
|
||||
}
|
||||
|
||||
public TreeModel getAllMaterialCategories() {
|
||||
return assignedMaterialsToOrderElementModel.getAllMaterialCategories();
|
||||
}
|
||||
|
||||
public double getTotalUnits() {
|
||||
double result = 0;
|
||||
|
||||
final OrderElement orderElement = getOrderElement();
|
||||
if (orderElement != null) {
|
||||
result = orderElement.getTotalMaterialAssigmentUnits();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalPrice() {
|
||||
BigDecimal result = new BigDecimal(0);
|
||||
|
||||
final OrderElement orderElement = getOrderElement();
|
||||
if (orderElement != null) {
|
||||
result = orderElement.getTotalMaterialAssigmentPrice();
|
||||
}
|
||||
return result.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private OrderElement getOrderElement() {
|
||||
return assignedMaterialsToOrderElementModel.getOrderElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* On selecting category, refresh {@link MaterialAssignment} associated with
|
||||
* selected {@link MaterialCategory}
|
||||
*/
|
||||
public void refreshMaterialAssigments() {
|
||||
final List<MaterialAssignment> materials = getAssignedMaterials();
|
||||
gridMaterials.setModel(new SimpleListModel(materials));
|
||||
Util.reloadBindings(gridMaterials);
|
||||
}
|
||||
|
||||
public List<MaterialAssignment> getAssignedMaterials() {
|
||||
final Treeitem treeitem = categoriesTree.getSelectedItem();
|
||||
return getAssignedMaterials(treeitem);
|
||||
}
|
||||
|
||||
private List<MaterialAssignment> getAssignedMaterials(Treeitem treeitem) {
|
||||
final MaterialCategory materialCategory = (treeitem != null) ? (MaterialCategory) treeitem.getValue() : null;
|
||||
return getAssignedMaterials(materialCategory);
|
||||
}
|
||||
|
||||
private List<MaterialAssignment> getAssignedMaterials(MaterialCategory materialCategory) {
|
||||
return assignedMaterialsToOrderElementModel.getAssignedMaterials(materialCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* On changing total price, recalculate unit price and refresh categories tree
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
public void updateTotalPrice(Row row) {
|
||||
final MaterialAssignment materialAssignment = (MaterialAssignment) row
|
||||
.getValue();
|
||||
Doublebox totalPrice = (Doublebox) row.getChildren().get(5);
|
||||
totalPrice.setValue(materialAssignment.getTotalPrice().doubleValue());
|
||||
refreshTotalPriceAndTotalUnits(materialAssignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh categoriesTree since it shows totalUnits and totalPrice as well
|
||||
*/
|
||||
private void refreshTotalPriceAndTotalUnits(MaterialAssignment materialAssignment) {
|
||||
final Treeitem item = findMaterialCategoryInTree(materialAssignment
|
||||
.getMaterial().getCategory(), categoriesTree);
|
||||
if (item != null) {
|
||||
// Reload categoriesTree
|
||||
categoriesTree.setModel(getMaterialCategories());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On changing unit price, recalculate total price and refresh categories tree
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
public void updateUnitPrice(Row row) {
|
||||
final MaterialAssignment materialAssignment = (MaterialAssignment) row.getValue();
|
||||
Doublebox unitPrice = (Doublebox) row.getChildren().get(4);
|
||||
unitPrice.setValue(materialAssignment.getUnitPrice().doubleValue());
|
||||
refreshTotalPriceAndTotalUnits(materialAssignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds which {@link Treeitem} in tree is associated with category
|
||||
*
|
||||
* @param category
|
||||
* @param tree
|
||||
* @return
|
||||
*/
|
||||
private Treeitem findMaterialCategoryInTree(MaterialCategory category, Tree tree) {
|
||||
for (Iterator i = tree.getItems().iterator(); i.hasNext(); ) {
|
||||
Treeitem treeitem = (Treeitem) i.next();
|
||||
final MaterialCategory materialCategory = (MaterialCategory) treeitem.getValue();
|
||||
if (category.equals(materialCategory)) {
|
||||
return treeitem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search materials on pressing search button
|
||||
*/
|
||||
public void searchMaterials() {
|
||||
final String text = txtSearchMaterial.getValue();
|
||||
final MaterialCategory materialCategory = getSelectedCategory(allCategoriesTree);
|
||||
assignedMaterialsToOrderElementModel.searchMaterials(text, materialCategory);
|
||||
Util.reloadBindings(lbFoundMaterials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link MaterialCategory} associated with selected {@link Treeitem} in {@link Tree}
|
||||
*
|
||||
* @param tree
|
||||
* @return
|
||||
*/
|
||||
private MaterialCategory getSelectedCategory(Tree tree) {
|
||||
final Treeitem treeitem = tree.getSelectedItem();
|
||||
return (treeitem != null) ? (MaterialCategory) treeitem.getValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get materials found on latest search
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Material> getMatchingMaterials() {
|
||||
return assignedMaterialsToOrderElementModel.getMatchingMaterials();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a list of selected {@link Material} to current {@link OrderElement}
|
||||
*/
|
||||
public void assignSelectedMaterials() {
|
||||
Set<Material> materials = getSelectedMaterials();
|
||||
if (materials.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(Material each: materials) {
|
||||
assignedMaterialsToOrderElementModel.addMaterialAssignment(each);
|
||||
}
|
||||
|
||||
categoriesTree.clearSelection();
|
||||
tbAssignedMaterials.setSelected(true);
|
||||
lbFoundMaterials.clearSelection();
|
||||
Util.reloadBindings(categoriesTree);
|
||||
Util.reloadBindings(gridMaterials);
|
||||
}
|
||||
|
||||
private Set<Material> getSelectedMaterials() {
|
||||
Set<Material> result = new HashSet<Material>();
|
||||
|
||||
final Set<Listitem> listitems = lbFoundMaterials.getSelectedItems();
|
||||
for (Listitem each: listitems) {
|
||||
final Material material = (Material) each.getValue();
|
||||
result.add(material);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public MaterialCategoryRenderer getMaterialCategoryRenderer() {
|
||||
return new MaterialCategoryRenderer();
|
||||
}
|
||||
|
||||
private class MaterialCategoryRenderer implements TreeitemRenderer {
|
||||
|
||||
/**
|
||||
* Copied verbatim from org.zkoss.zul.Tree;
|
||||
*/
|
||||
@Override
|
||||
public void render(Treeitem ti, Object node) throws Exception {
|
||||
final MaterialCategory materialCategory = (MaterialCategory) node;
|
||||
|
||||
Label lblName = new Label(materialCategory.getName());
|
||||
|
||||
Treerow tr = null;
|
||||
ti.setValue(node);
|
||||
if (ti.getTreerow() == null) {
|
||||
tr = new Treerow();
|
||||
tr.setParent(ti);
|
||||
ti.setOpen(true); // Expand node
|
||||
} else {
|
||||
tr = ti.getTreerow();
|
||||
tr.getChildren().clear();
|
||||
}
|
||||
// Add category name
|
||||
Treecell cellName = new Treecell();
|
||||
lblName.setParent(cellName);
|
||||
cellName.setParent(tr);
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialCategoryWithUnitsAndPriceRenderer getMaterialCategoryWithUnitsAndPriceRenderer() {
|
||||
return new MaterialCategoryWithUnitsAndPriceRenderer();
|
||||
}
|
||||
|
||||
private class MaterialCategoryWithUnitsAndPriceRenderer implements TreeitemRenderer {
|
||||
|
||||
/**
|
||||
* Copied verbatim from org.zkoss.zul.Tree;
|
||||
*/
|
||||
@Override
|
||||
public void render(Treeitem ti, Object node) throws Exception {
|
||||
final MaterialCategory materialCategory = (MaterialCategory) node;
|
||||
|
||||
Label lblName = new Label(materialCategory.getName());
|
||||
Label lblUnits = new Label(new Double(getUnits(materialCategory)).toString());
|
||||
Label lblPrice = new Label(getPrice(materialCategory).toString());
|
||||
|
||||
Treerow tr = null;
|
||||
ti.setValue(node);
|
||||
if (ti.getTreerow() == null) {
|
||||
tr = new Treerow();
|
||||
tr.setParent(ti);
|
||||
ti.setOpen(true); // Expand node
|
||||
} else {
|
||||
tr = ti.getTreerow();
|
||||
tr.getChildren().clear();
|
||||
}
|
||||
// Add category name
|
||||
Treecell cellName = new Treecell();
|
||||
lblName.setParent(cellName);
|
||||
cellName.setParent(tr);
|
||||
|
||||
// Add total assigned material units in category
|
||||
Treecell cellUnits = new Treecell();
|
||||
lblUnits.setParent(cellUnits);
|
||||
cellUnits.setParent(tr);
|
||||
|
||||
// Add total price for assigned materials in category
|
||||
Treecell cellPrice = new Treecell();
|
||||
lblPrice.setParent(cellPrice);
|
||||
cellPrice.setParent(tr);
|
||||
}
|
||||
|
||||
private double getUnits(MaterialCategory materialCategory) {
|
||||
return assignedMaterialsToOrderElementModel.getUnits(materialCategory);
|
||||
}
|
||||
|
||||
private BigDecimal getPrice(MaterialCategory materialCategory) {
|
||||
return assignedMaterialsToOrderElementModel.getPrice(materialCategory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On clicking remove {@link MaterialAssignment}, shows dialog for
|
||||
* confirming removing selected element
|
||||
*
|
||||
* @param materialAssignment
|
||||
*/
|
||||
public void showRemoveMaterialAssignmentDlg(MaterialAssignment materialAssignment) {
|
||||
try {
|
||||
int status = Messagebox.show(_("Delete item {0}. Are you sure?", materialAssignment.getMaterial().getCode()),
|
||||
_("Delete"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
|
||||
if (Messagebox.OK == status) {
|
||||
removeMaterialAssignment(materialAssignment);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error(_("Error on showing delete materialAssignment: ", materialAssignment.getId()), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeMaterialAssignment(MaterialAssignment materialAssignment) {
|
||||
assignedMaterialsToOrderElementModel.removeMaterialAssignment(materialAssignment);
|
||||
Util.reloadBindings(gridMaterials);
|
||||
// Reload categoriesTree
|
||||
categoriesTree.setModel(getMaterialCategories());
|
||||
}
|
||||
|
||||
/**
|
||||
* On clicking Split button, shows dialog for splitting selected
|
||||
* {@link MaterialAssignment} into two
|
||||
*
|
||||
* @param materialAssignment
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void showSplitMaterialAssignmentDlg(MaterialAssignment materialAssignment) {
|
||||
MessageboxDlg dialogSplitAssignment;
|
||||
|
||||
final String message = _("Create new material assignment out of material assignment {0}. Are you sure?",
|
||||
materialAssignment.getMaterial().getCode());
|
||||
|
||||
Map args = new HashMap();
|
||||
args.put("message", message);
|
||||
args.put("title", _("Split new assignment"));
|
||||
args.put("OK", Messagebox.OK);
|
||||
args.put("CANCEL", Messagebox.CANCEL);
|
||||
args.put("icon", Messagebox.QUESTION);
|
||||
|
||||
dialogSplitAssignment = (MessageboxDlg) Executions
|
||||
.createComponents("/orders/_splitMaterialAssignmentDlg.zul",
|
||||
self, args);
|
||||
Doublebox dbUnits = (Doublebox) dialogSplitAssignment.getFellowIfAny("dbUnits");
|
||||
dbUnits.setValue(materialAssignment.getUnits());
|
||||
try {
|
||||
dialogSplitAssignment.doModal();
|
||||
int status = dialogSplitAssignment.getResult();
|
||||
if (Messagebox.OK == status) {
|
||||
splitMaterialAssignment(materialAssignment, dbUnits.getValue());
|
||||
}
|
||||
} catch (SuspendNotAllowedException e) {
|
||||
LOG.error(_("Error on splitting element: ", materialAssignment.getId()), e);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error(_("Error on splitting element: ", materialAssignment.getId()), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MaterialAssignment} out of materialAssignment, but
|
||||
* setting its units attribute to units.
|
||||
*
|
||||
* materialAssignment passed as parameter decreases its units attribute in units
|
||||
*
|
||||
* @param materialAssignment
|
||||
* @param units
|
||||
*/
|
||||
private void splitMaterialAssignment(MaterialAssignment materialAssignment, double units) {
|
||||
MaterialAssignment newMaterialAssignment = MaterialAssignment.create(materialAssignment);
|
||||
double currentUnits = materialAssignment.getUnits();
|
||||
if (units > currentUnits) {
|
||||
units = currentUnits;
|
||||
currentUnits = 0;
|
||||
} else {
|
||||
currentUnits -= units;
|
||||
}
|
||||
newMaterialAssignment.setUnits(units);
|
||||
materialAssignment.setUnits(currentUnits);
|
||||
assignedMaterialsToOrderElementModel.addMaterialAssignment(newMaterialAssignment);
|
||||
Util.reloadBindings(gridMaterials);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* This file is part of ###PROJECT_NAME###
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* 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.navalplanner.web.orders;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.navalplanner.business.materials.daos.IMaterialCategoryDAO;
|
||||
import org.navalplanner.business.materials.daos.IMaterialDAO;
|
||||
import org.navalplanner.business.materials.entities.Material;
|
||||
import org.navalplanner.business.materials.entities.MaterialAssignment;
|
||||
import org.navalplanner.business.materials.entities.MaterialCategory;
|
||||
import org.navalplanner.business.orders.daos.IOrderElementDAO;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.zkoss.ganttz.util.MutableTreeModel;
|
||||
import org.zkoss.zul.TreeModel;
|
||||
|
||||
/**
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
@Service
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
public class AssignedMaterialsToOrderElementModel implements
|
||||
IAssignedMaterialsToOrderElementModel {
|
||||
|
||||
@Autowired
|
||||
private IMaterialCategoryDAO categoryDAO;
|
||||
|
||||
@Autowired
|
||||
private IMaterialDAO materialDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderElementDAO orderElementDAO;
|
||||
|
||||
private IOrderElementModel orderElementModel;
|
||||
|
||||
private OrderElement orderElement;
|
||||
|
||||
private MutableTreeModel<MaterialCategory> materialCategories = MutableTreeModel
|
||||
.create(MaterialCategory.class);
|
||||
|
||||
private MutableTreeModel<MaterialCategory> allMaterialCategories = MutableTreeModel
|
||||
.create(MaterialCategory.class);
|
||||
|
||||
private List<Material> matchingMaterials = new ArrayList<Material>();
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void initEdit(IOrderElementModel orderElementModel) {
|
||||
this.orderElementModel = orderElementModel;
|
||||
this.orderElement = this.orderElementModel.getOrderElement();
|
||||
orderElementDAO.reattach(this.orderElement);
|
||||
materialCategories = MutableTreeModel.create(MaterialCategory.class);
|
||||
initializeMaterialAssigments(this.orderElement.getMaterialAssignments());
|
||||
|
||||
// Initialize matching materials
|
||||
matchingMaterials.clear();
|
||||
matchingMaterials.addAll(materialDAO.getAll());
|
||||
initializeMaterials(matchingMaterials);
|
||||
}
|
||||
|
||||
private void initializeMaterialAssigments(
|
||||
Set<MaterialAssignment> materialAssignments) {
|
||||
for (MaterialAssignment each : materialAssignments) {
|
||||
each.getStatus();
|
||||
initializeMaterialCategory(each.getMaterial().getCategory());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void initializeMaterialCategories(
|
||||
Collection<MaterialCategory> materialCategories) {
|
||||
for (MaterialCategory each : materialCategories) {
|
||||
initializeMaterialCategory(each);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeMaterialCategory(MaterialCategory materialCategory) {
|
||||
materialCategory.getName();
|
||||
initializeMaterials(materialCategory.getMaterials());
|
||||
initializeMaterialCategories(materialCategory.getSubcategories());
|
||||
}
|
||||
|
||||
private void initializeMaterials(Collection<Material> materials) {
|
||||
for (Material each : materials) {
|
||||
initializeMaterial(each);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeMaterial(Material material) {
|
||||
material.getDescription();
|
||||
material.getCategory().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderElement getOrderElement() {
|
||||
return orderElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public MutableTreeModel<MaterialCategory> getMaterialCategories() {
|
||||
if (orderElement != null && materialCategories.isEmpty()) {
|
||||
feedTree(materialCategories, orderElement.getMaterialAssignments());
|
||||
initializeMaterialCategories(materialCategories.asList());
|
||||
}
|
||||
return materialCategories;
|
||||
}
|
||||
|
||||
private void feedTree(MutableTreeModel<MaterialCategory> tree,
|
||||
Set<MaterialAssignment> materialAssignments) {
|
||||
for (MaterialAssignment each : materialAssignments) {
|
||||
final Material material = (Material) each.getMaterial();
|
||||
addCategory(tree, material.getCategory());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds category to treeModel
|
||||
*
|
||||
* If category.parent is not in treeModel add it to treeModel recursively.
|
||||
*
|
||||
*/
|
||||
private void addCategory(
|
||||
MutableTreeModel<MaterialCategory> materialCategories,
|
||||
MaterialCategory materialCategory) {
|
||||
|
||||
categoryDAO.reattach(materialCategory);
|
||||
final MaterialCategory parent = materialCategory.getParent();
|
||||
if (parent == null) {
|
||||
if (!materialCategories.contains(parent, materialCategory)) {
|
||||
materialCategories.addToRoot(materialCategory);
|
||||
}
|
||||
} else {
|
||||
if (!materialCategories.contains(parent, materialCategory)) {
|
||||
addCategory(materialCategories, parent);
|
||||
materialCategories.add(parent, materialCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public TreeModel getAllMaterialCategories() {
|
||||
if (allMaterialCategories.isEmpty()) {
|
||||
feedTree(allMaterialCategories, categoryDAO.getAll());
|
||||
initializeMaterialCategories(allMaterialCategories.asList());
|
||||
}
|
||||
return allMaterialCategories;
|
||||
}
|
||||
|
||||
private void feedTree(MutableTreeModel<MaterialCategory> tree,
|
||||
List<MaterialCategory> materialCategories) {
|
||||
for (MaterialCategory each : materialCategories) {
|
||||
addCategory(tree, each);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MaterialAssignment> getAssignedMaterials(
|
||||
MaterialCategory materialCategory) {
|
||||
List<MaterialAssignment> result = new ArrayList<MaterialAssignment>();
|
||||
if (orderElement != null) {
|
||||
for (MaterialAssignment materialAssigment : orderElement
|
||||
.getMaterialAssignments()) {
|
||||
final Material material = materialAssigment.getMaterial();
|
||||
if (materialCategory == null
|
||||
|| materialCategory.equals(material.getCategory())) {
|
||||
result.add(materialAssigment);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void searchMaterials(String text, MaterialCategory materialCategory) {
|
||||
matchingMaterials = materialDAO
|
||||
.findMaterialsInCategoryAndSubCategories(text, materialCategory);
|
||||
initializeMaterials(matchingMaterials);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Material> getMatchingMaterials() {
|
||||
return matchingMaterials;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void addMaterialAssignment(Material material) {
|
||||
MaterialAssignment materialAssigment = MaterialAssignment
|
||||
.create(material);
|
||||
materialAssigment.setEstimatedAvailability(orderElement.getInitDate());
|
||||
addMaterialAssignment(materialAssigment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void addMaterialAssignment(MaterialAssignment materialAssignment) {
|
||||
orderElement.addMaterialAssignment(materialAssignment);
|
||||
// Add material category to materialCategories tree
|
||||
final MaterialCategory materialCategory = materialAssignment.getMaterial().getCategory();
|
||||
addCategory(materialCategories, materialCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMaterialAssignment(MaterialAssignment materialAssignment) {
|
||||
orderElement.removeMaterialAssignment(materialAssignment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getUnits(MaterialCategory materialCategory) {
|
||||
double result = 0;
|
||||
if (orderElement != null) {
|
||||
for (MaterialAssignment materialAssignment : orderElement
|
||||
.getMaterialAssignments()) {
|
||||
final Material material = materialAssignment.getMaterial();
|
||||
if (materialCategory.equals(material.getCategory())) {
|
||||
result += materialAssignment.getUnits();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getPrice(MaterialCategory materialCategory) {
|
||||
BigDecimal result = new BigDecimal(0);
|
||||
if (orderElement != null) {
|
||||
for (MaterialAssignment materialAssignment : orderElement
|
||||
.getMaterialAssignments()) {
|
||||
final Material material = materialAssignment.getMaterial();
|
||||
if (materialCategory.equals(material.getCategory())) {
|
||||
result = result.add(materialAssignment.getTotalPrice());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* This file is part of ###PROJECT_NAME###
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* 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.navalplanner.web.orders;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.materials.entities.Material;
|
||||
import org.navalplanner.business.materials.entities.MaterialAssignment;
|
||||
import org.navalplanner.business.materials.entities.MaterialCategory;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.zkoss.zul.TreeModel;
|
||||
|
||||
|
||||
/**
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
public interface IAssignedMaterialsToOrderElementModel {
|
||||
|
||||
/**
|
||||
* Add a new {@link MaterialAssignment} out of {@link Material}
|
||||
*
|
||||
* @param each
|
||||
*/
|
||||
void addMaterialAssignment(Material material);
|
||||
|
||||
/**
|
||||
* Add a new {@link MaterialAssignment} out of existing {@link MaterialAssignment}
|
||||
*
|
||||
* @param materialAssignment
|
||||
*/
|
||||
void addMaterialAssignment(MaterialAssignment materialAssignment);
|
||||
|
||||
TreeModel getAllMaterialCategories();
|
||||
|
||||
List<MaterialAssignment> getAssignedMaterials(MaterialCategory materialCategory);
|
||||
|
||||
/**
|
||||
* Returns list of {@link Material} found after executing latest search
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Material> getMatchingMaterials();
|
||||
|
||||
/**
|
||||
* Get list of {@link MaterialCategory} assigned to current {@link OrderElement}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TreeModel getMaterialCategories();
|
||||
|
||||
OrderElement getOrderElement();
|
||||
|
||||
/**
|
||||
* Calculates sum of price for all {@link MaterialAssignment} which belong
|
||||
* to {@link MaterialCategory}
|
||||
*
|
||||
* @param materialCategory
|
||||
* @return
|
||||
*/
|
||||
BigDecimal getPrice(MaterialCategory materialCategory);
|
||||
|
||||
/**
|
||||
* Calculates sum of units for all {@link MaterialAssignment} which belong
|
||||
* to {@link MaterialCategory}
|
||||
*
|
||||
* @param materialCategory
|
||||
* @return
|
||||
*/
|
||||
double getUnits(MaterialCategory materialCategory);
|
||||
|
||||
void initEdit(IOrderElementModel orderElementModel);
|
||||
|
||||
void removeMaterialAssignment(MaterialAssignment materialAssignment);
|
||||
|
||||
/**
|
||||
* Searches materials in categories and its subcategories by code and
|
||||
* description
|
||||
*
|
||||
* @param code
|
||||
* @param materialCategory
|
||||
*/
|
||||
void searchMaterials(String text, MaterialCategory materialCategory);
|
||||
}
|
||||
|
|
@ -115,12 +115,14 @@ public class OrderCRUDController extends GenericForwardComposer {
|
|||
OrderElementController orderElementController = new OrderElementController();
|
||||
orderElementController.doAfterCompose(comp
|
||||
.getFellow("editOrderElement"));
|
||||
|
||||
setupOrderElementTreeController(comp, orderElementController);
|
||||
setupDetailsOrderElementController(comp);
|
||||
setupAsignedHoursToOrderElementController(comp);
|
||||
setupManageOrderElementAdvancesController(comp);
|
||||
setupAssignedLabelsToOrderElementController(comp);
|
||||
setupAssignedCriterionRequirementsToOrderElementController(comp);
|
||||
setupAssignedMaterialsToOrderElementController(comp);
|
||||
}
|
||||
|
||||
private void setupOrderElementTreeController(Component comp,
|
||||
|
|
@ -178,6 +180,16 @@ public class OrderCRUDController extends GenericForwardComposer {
|
|||
.getVariable("assignedCriterionRequirementController", true);
|
||||
}
|
||||
|
||||
private AssignedMaterialsToOrderElementController assignedMaterialsController;
|
||||
|
||||
private void setupAssignedMaterialsToOrderElementController(
|
||||
Component comp) throws Exception {
|
||||
Component orderElementMaterials = editWindow
|
||||
.getFellowIfAny("orderElementMaterials");
|
||||
assignedMaterialsController = (AssignedMaterialsToOrderElementController) orderElementMaterials
|
||||
.getVariable("assignedMaterialsController", true);
|
||||
}
|
||||
|
||||
public List<Order> getOrders() {
|
||||
return orderModel.getOrders();
|
||||
}
|
||||
|
|
@ -315,6 +327,7 @@ public class OrderCRUDController extends GenericForwardComposer {
|
|||
manageOrderElementAdvancesController.openWindow(orderElementModel);
|
||||
assignedLabelsController.openWindow(orderElementModel);
|
||||
assignedCriterionRequirementController.openWindow(orderElementModel);
|
||||
assignedMaterialsController.openWindow(orderElementModel);
|
||||
}
|
||||
|
||||
private void clearEditWindow() {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
<component-class>org.navalplanner.web.common.components.NewDataSortableColumn</component-class>
|
||||
<extends>column</extends>
|
||||
</component>
|
||||
|
||||
|
||||
<component>
|
||||
<component-name>schedulingStateToggler</component-name>
|
||||
<component-class>org.navalplanner.web.orders.SchedulingStateToggler</component-class>
|
||||
|
|
@ -61,4 +61,13 @@
|
|||
</annotation>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<component-name>doublebox</component-name>
|
||||
<extends>doublebox</extends>
|
||||
<property>
|
||||
<property-name>format</property-name>
|
||||
<property-value>###,##0.00####</property-value>
|
||||
</property>
|
||||
</component>
|
||||
|
||||
</language-addon>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
<?component name="listOrderElementAdvances" inline="true" macroURI="_listOrderElementAdvances.zul"?>
|
||||
<?component name="listOrderElementLabels" inline="true" macroURI="_listOrderElementLabels.zul"?>
|
||||
<?component name="listOrderElementCriterionRequirements" inline="true" macroURI="_listOrderElementCriterionRequirements.zul"?>
|
||||
<?component name="listOrderElementMaterials" inline="true" macroURI="_listOrderElementMaterials.zul"?>
|
||||
|
||||
<window id="${arg.top_id}">
|
||||
<tabbox>
|
||||
<tabs>
|
||||
|
|
@ -35,6 +37,7 @@
|
|||
<tab label="${i18n:_('Label')}" />
|
||||
<tab id="tabRequirements" label="${i18n:_('Criterion Requirement')}"
|
||||
onClick = "controller.reloadHoursGroupOrder();"/>
|
||||
<tab label="${i18n:_('Materials')}" />
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<tabpanel>
|
||||
|
|
@ -111,6 +114,9 @@
|
|||
<tabpanel>
|
||||
<listOrderElementCriterionRequirements id="orderElementCriterionRequirements"/>
|
||||
</tabpanel>
|
||||
<tabpanel>
|
||||
<listOrderElementMaterials id="orderElementMaterials"/>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
<hbox>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
<!--
|
||||
This file is part of ###PROJECT_NAME###
|
||||
|
||||
Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
Desenvolvemento Tecnolóxico de Galicia
|
||||
|
||||
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/>.
|
||||
-->
|
||||
|
||||
<vbox id="${arg.id}"
|
||||
apply="org.navalplanner.web.orders.AssignedMaterialsToOrderElementController" >
|
||||
|
||||
<zscript>
|
||||
Object[] unitTypes = org.navalplanner.business.materials.entities.UnitTypeEnum
|
||||
.values();
|
||||
Object[] materialStatus = org.navalplanner.business.materials.entities.MaterialStatusEnum
|
||||
.values();
|
||||
</zscript>
|
||||
|
||||
<tabbox mold="accordion-lite">
|
||||
<tabs>
|
||||
<tab id="tbAssignedMaterials" label="${i18n:_('Materials')}" image="common/img/ico_bajar.png"/>
|
||||
<tab label="${i18n:_('Material search')}" image="common/img/ico_bajar.png"/>
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<tabpanel>
|
||||
<hbox>
|
||||
<!-- Categories -->
|
||||
<vbox>
|
||||
<panel title="${i18n:_('Categories')}" border="normal">
|
||||
<panelchildren>
|
||||
<toolbarbutton style="text-decoration: none" label="${i18n:_('Unselect')}" onClick="categoriesTree.clearSelection()" />
|
||||
<tree id="categoriesTree"
|
||||
fixedLayout="false"
|
||||
width="280px" rows="10" vflex="true" multiple="false"
|
||||
onSelect="assignedMaterialsController.refreshMaterialAssigments()">
|
||||
<treecols>
|
||||
<treecol label="Name" />
|
||||
<treecol label="Units" width="50px" />
|
||||
<treecol label="Price" width="50px" />
|
||||
</treecols>
|
||||
</tree>
|
||||
</panelchildren>
|
||||
</panel>
|
||||
</vbox>
|
||||
|
||||
<!-- Materials -->
|
||||
<vbox>
|
||||
<panel title="${i18n:_('Materials')}"
|
||||
border="normal">
|
||||
<panelchildren>
|
||||
<newdatasortablegrid id="gridMaterials"
|
||||
fixedLayout="false"
|
||||
model="@{assignedMaterialsController.assignedMaterials}">
|
||||
<columns>
|
||||
<newdatasortablecolumn label="${i18n:_('Code')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Date')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Units')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Unit type')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Unit price')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Total price')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Category')}" />
|
||||
<newdatasortablecolumn label="${i18n:_('Status')}" />
|
||||
<newdatasortablecolumn label="" />
|
||||
</columns>
|
||||
<rows>
|
||||
<row self="@{each='assignedMaterial'}" value="@{assignedMaterial}">
|
||||
<textbox value="@{assignedMaterial.material.code}"
|
||||
constraint="no empty:${i18n:_('cannot be null or empty')}"
|
||||
readonly="true" />
|
||||
<datebox value="@{assignedMaterial.estimatedAvailability}" />
|
||||
<doublebox value="@{assignedMaterial.units}"
|
||||
onChange="assignedMaterialsController.updateTotalPrice(self.parent)" />
|
||||
<listbox mold="select" model="@{unitTypes}"
|
||||
selectedItem="@{assignedMaterial.material.unitType}" disabled="true" />
|
||||
<doublebox value="@{assignedMaterial.unitPrice}"
|
||||
onChange="assignedMaterialsController.updateTotalPrice(self.parent)" />
|
||||
<doublebox value="@{assignedMaterial.totalPrice}"
|
||||
onChange="assignedMaterialsController.updateUnitPrice(self.parent)" />
|
||||
<listbox mold="select" model="@{materialStatus}"
|
||||
selectedItem="@{assignedMaterial.status}"/>
|
||||
<label value="@{assignedMaterial.material.category.name}" width="150px" />
|
||||
<hbox>
|
||||
<button sclass="icono"
|
||||
image="/common/img/ico_borrar1.png"
|
||||
hoverImage="/common/img/ico_borrar.png"
|
||||
tooltiptext="${i18n:_('Delete')}"
|
||||
onClick="assignedMaterialsController.showRemoveMaterialAssignmentDlg(self.parent.parent.value)">
|
||||
</button>
|
||||
<button label="${i18n:_('Split')}"
|
||||
tooltiptext="${i18n:_('Split assignment')}"
|
||||
onClick="assignedMaterialsController.showSplitMaterialAssignmentDlg(self.parent.parent.value)">
|
||||
</button>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</newdatasortablegrid>
|
||||
</panelchildren>
|
||||
</panel>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</tabpanel>
|
||||
|
||||
<tabpanel>
|
||||
<!-- Material search -->
|
||||
<hbox>
|
||||
<!-- Categories -->
|
||||
<vbox>
|
||||
<panel title="${i18n:_('Categories')}" border="normal">
|
||||
<panelchildren>
|
||||
<toolbarbutton style="text-decoration: none" label="${i18n:_('Unselect')}" onClick="allCategoriesTree.clearSelection()" />
|
||||
<tree id="allCategoriesTree"
|
||||
width="280px" rows="10" vflex="true" multiple="false">
|
||||
<treecols>
|
||||
<treecol label="Name" />
|
||||
</treecols>
|
||||
</tree>
|
||||
</panelchildren>
|
||||
</panel>
|
||||
</vbox>
|
||||
|
||||
<vbox>
|
||||
|
||||
<!-- Found materials -->
|
||||
<panel title="${i18n:_('Materials')}" border="normal">
|
||||
<panelchildren>
|
||||
|
||||
<!-- Search textbox -->
|
||||
<hbox>
|
||||
<textbox id="txtSearchMaterial" width="250px" style="margin-top: 5px" />
|
||||
<button label="${i18n:_('Search')}" style="margin-bottom: 5px"
|
||||
onClick="assignedMaterialsController.searchMaterials()"/>
|
||||
<button label="${i18n:_('Assign')}"
|
||||
onClick="assignedMaterialsController.assignSelectedMaterials()" />
|
||||
</hbox>
|
||||
|
||||
<listbox id="lbFoundMaterials"
|
||||
fixedLayout="true"
|
||||
model="@{assignedMaterialsController.matchingMaterials}">
|
||||
<listhead sizable="true">
|
||||
<listheader label="${i18n:_('Code')}" />
|
||||
<listheader label="${i18n:_('Name')}" />
|
||||
<listheader label="${i18n:_('Unit type')}" />
|
||||
<listheader label="${i18n:_('Unit price')}" />
|
||||
<listheader label="${i18n:_('Category')}" />
|
||||
</listhead>
|
||||
<listitem self="@{each='material'}" value="@{material}">
|
||||
<listcell label="@{material.code}" />
|
||||
<listcell label="@{material.description}" />
|
||||
<listcell>
|
||||
<listbox mold="select"
|
||||
model="@{unitTypes}"
|
||||
selectedItem="@{material.unitType}"
|
||||
disabled="true" />
|
||||
</listcell>
|
||||
<listcell label="@{material.defaultUnitPrice}" />
|
||||
<listcell label="@{material.category.name}" />
|
||||
</listitem>
|
||||
</listbox>
|
||||
</panelchildren>
|
||||
</panel>
|
||||
</vbox>
|
||||
|
||||
</hbox>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
|
||||
</vbox>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<window title="${arg.title}" border="normal" width="250pt" closable="true"
|
||||
use="org.zkoss.zul.impl.MessageboxDlg">
|
||||
<hbox>
|
||||
<div class="${arg.icon}"/>
|
||||
<div sclass="z-messagebox" width="210pt">
|
||||
<label value="${arg.message}" multiline="true"/>
|
||||
</div>
|
||||
</hbox>
|
||||
<separator spacing="20px"/>
|
||||
<grid>
|
||||
<columns>
|
||||
<column />
|
||||
<column />
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<label style="font-weight: bold" value="${i18n:_('Units')}:" width="150px" />
|
||||
<doublebox id="dbUnits" width="200px" />
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<separator bar="true"/>
|
||||
<hbox style="margin-left:auto; margin-right:auto">
|
||||
<button id="btnOk" identity="${arg.OK}" sclass="z-messagebox-btn"
|
||||
use="org.zkoss.zul.impl.MessageboxDlg$Button" />
|
||||
<button id="btnCancel" identity="${arg.CANCEL}" sclass="z-messagebox-btn"
|
||||
use="org.zkoss.zul.impl.MessageboxDlg$Button" />
|
||||
</hbox>
|
||||
</window>
|
||||
|
|
@ -60,6 +60,9 @@
|
|||
<value>
|
||||
org/navalplanner/business/common/entities/Configuration.hbm.xml
|
||||
</value>
|
||||
<value>
|
||||
org/navalplanner/business/materials/entities/Materials.hbm.xml
|
||||
</value>
|
||||
</list>
|
||||
</property>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue