ItEr44S11CUImportarTraballoRealizadoPorSubcontrataItEr43S14: Added page to manage subcontracted tasks list.

This commit is contained in:
Manuel Rego Casasnovas 2010-01-22 08:16:42 +01:00 committed by Javier Moran Rua
parent 93ed7416bf
commit e5242a5c7d
14 changed files with 638 additions and 4 deletions

View file

@ -20,6 +20,8 @@
package org.navalplanner.business.planner.daos;
import java.util.List;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
@ -33,4 +35,6 @@ public interface ISubcontractedTaskDataDAO extends
boolean existsInAnohterTransaction(Long id);
List<SubcontractedTaskData> getAll();
}

View file

@ -20,6 +20,8 @@
package org.navalplanner.business.planner.daos;
import java.util.List;
import org.navalplanner.business.common.daos.GenericDAOHibernate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
@ -55,4 +57,9 @@ public class SubcontractedTaskDataDAO extends
}
}
@Override
public List<SubcontractedTaskData> getAll() {
return list(SubcontractedTaskData.class);
}
}

View file

@ -239,4 +239,9 @@ public class SubcontractedTaskData extends BaseEntity {
return state;
}
public boolean isSendable() {
return state.isSendable()
&& externalCompany.getInteractsWithApplications();
}
}

View file

@ -197,8 +197,8 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
subItem(_("Company view"), "/planner/index.zul;company_scheduling","01-introducion.html"),
subItem(_("General resource allocation"),"/planner/index.zul;company_load","01-introducion.html#id1"),
subItem(_("Orders list"), "/planner/index.zul;orders_list","01-introducion.html#id2"),
subItem(_("Templates list"), "/templates/templates.zul",""));
subItem(_("Templates list"), "/templates/templates.zul", ""),
subItem(_("Subcontracted tasks list"),"/subcontract/subcontractedTasks.zul", ""));
topItem(_("Resources"), "/resources/worker/worker.zul", "",
subItem(_("Workers List"), "/resources/worker/worker.zul","05-recursos.html#xesti-n-de-traballadores"),

View file

@ -0,0 +1,44 @@
/*
* 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.subcontract;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
import org.navalplanner.web.subcontract.exceptions.ConnectionProblemsException;
import org.navalplanner.web.subcontract.exceptions.UnrecoverableErrorServiceException;
/**
* Contract for {@link SubcontractedTasksModel}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public interface ISubcontractedTasksModel {
List<SubcontractedTaskData> getSubcontractedTasks();
String getOrderCode(SubcontractedTaskData subcontractedTaskData);
void sendToSubcontractor(SubcontractedTaskData subcontractedTaskData)
throws ValidationException, ConnectionProblemsException,
UnrecoverableErrorServiceException;
}

View file

@ -0,0 +1,168 @@
/*
* 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.subcontract;
import static org.navalplanner.web.I18nHelper._;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.MessagesForUser;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.subcontract.exceptions.ConnectionProblemsException;
import org.navalplanner.web.subcontract.exceptions.UnrecoverableErrorServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Label;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.api.Window;
/**
* Controller for operations related with subcontracted tasks.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@org.springframework.stereotype.Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class SubcontractedTasksController extends GenericForwardComposer {
private Window window;
private Component messagesContainer;
private IMessagesForUser messagesForUser;
@Autowired
private ISubcontractedTasksModel subcontractedTasksModel;
private SubcontractedTasksRenderer subcontractedTasksRenderer = new SubcontractedTasksRenderer();
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
window = (Window) comp;
window.setVariable("controller", this, true);
messagesForUser = new MessagesForUser(messagesContainer);
}
public List<SubcontractedTaskData> getSubcontractedTasks() {
return subcontractedTasksModel.getSubcontractedTasks();
}
public SubcontractedTasksRenderer getSubcontractedTasksRenderer() {
return subcontractedTasksRenderer;
}
private class SubcontractedTasksRenderer implements RowRenderer {
@Override
public void render(Row row, Object data) throws Exception {
SubcontractedTaskData subcontractedTaskData = (SubcontractedTaskData) data;
row.setValue(subcontractedTaskData);
appendLabel(row, toString(subcontractedTaskData
.getSubcontratationDate()));
appendLabel(row, toString(subcontractedTaskData
.getSubcontractCommunicationDate()));
appendLabel(row, getExternalCompany(subcontractedTaskData));
appendLabel(row, getOrderCode(subcontractedTaskData));
appendLabel(row, subcontractedTaskData.getSubcontractedCode());
appendLabel(row, getTaskName(subcontractedTaskData));
appendLabel(row, subcontractedTaskData.getWorkDescription());
appendLabel(row, toString(subcontractedTaskData
.getSubcontractPrice()));
appendLabel(row, toString(subcontractedTaskData.getState()));
appendOperations(row, subcontractedTaskData);
}
private String toString(Object object) {
if (object == null) {
return "";
}
return object.toString();
}
private void appendLabel(Row row, String label) {
row.appendChild(new Label(label));
}
private String getOrderCode(SubcontractedTaskData subcontractedTaskData) {
return subcontractedTasksModel.getOrderCode(subcontractedTaskData);
}
private String getTaskName(SubcontractedTaskData subcontractedTaskData) {
return subcontractedTaskData.getTask().getName();
}
private String getExternalCompany(
SubcontractedTaskData subcontractedTaskData) {
return subcontractedTaskData.getExternalCompany().getName();
}
private void appendOperations(Row row,
SubcontractedTaskData subcontractedTaskData) {
row.appendChild(getSendButton(subcontractedTaskData));
}
private Button getSendButton(
final SubcontractedTaskData subcontractedTaskData) {
Button sendButton = new Button(_("Send"));
sendButton.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
try {
subcontractedTasksModel
.sendToSubcontractor(subcontractedTaskData);
messagesForUser.showMessage(Level.INFO,
_("Subcontracted task sent successfully"));
} catch (UnrecoverableErrorServiceException e) {
messagesForUser
.showMessage(Level.ERROR, e.getMessage());
} catch (ConnectionProblemsException e) {
messagesForUser
.showMessage(Level.ERROR, e.getMessage());
} catch (ValidationException e) {
messagesForUser.showInvalidValues(e);
}
Util.reloadBindings(window);
}
});
sendButton.setDisabled(!subcontractedTaskData.isSendable());
return sendButton;
}
}
}

View file

@ -0,0 +1,209 @@
/*
* 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.subcontract;
import static org.navalplanner.web.I18nHelper._;
import java.util.Date;
import java.util.List;
import javax.ws.rs.WebApplicationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.externalcompanies.entities.ExternalCompany;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.planner.daos.ISubcontractedTaskDataDAO;
import org.navalplanner.business.planner.entities.SubcontractState;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
import org.navalplanner.business.planner.entities.Task;
import org.navalplanner.web.subcontract.exceptions.ConnectionProblemsException;
import org.navalplanner.web.subcontract.exceptions.UnrecoverableErrorServiceException;
import org.navalplanner.ws.common.api.ConstraintViolationDTO;
import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO;
import org.navalplanner.ws.common.api.InstanceConstraintViolationsListDTO;
import org.navalplanner.ws.common.api.OrderElementDTO;
import org.navalplanner.ws.common.impl.ConfigurationOrderElementConverter;
import org.navalplanner.ws.common.impl.OrderElementConverter;
import org.navalplanner.ws.common.impl.Util;
import org.navalplanner.ws.subcontract.api.SubcontractedTaskDataDTO;
import org.navalplanner.ws.subcontract.impl.SubcontractedTaskDataConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* Model for operations related with subcontracted tasks.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class SubcontractedTasksModel implements ISubcontractedTasksModel {
private static Log LOG = LogFactory.getLog(SubcontractedTasksModel.class);
@Autowired
private ISubcontractedTaskDataDAO subcontractedTaskDataDAO;
@Autowired
private IOrderElementDAO orderElementDAO;
@Autowired
private IConfigurationDAO configurationDAO;
@Override
@Transactional(readOnly = true)
public List<SubcontractedTaskData> getSubcontractedTasks() {
List<SubcontractedTaskData> result = subcontractedTaskDataDAO.getAll();
for (SubcontractedTaskData subcontractedTaskData : result) {
forceLoadExternalCompany(subcontractedTaskData);
}
return result;
}
private void forceLoadExternalCompany(
SubcontractedTaskData subcontractedTaskData) {
subcontractedTaskData.getExternalCompany().getName();
}
@Override
@Transactional(readOnly = true)
public String getOrderCode(SubcontractedTaskData subcontractedTaskData) {
Task task = subcontractedTaskData.getTask();
OrderElement orderElement = orderElementDAO
.loadOrderAvoidingProxyFor(task.getOrderElement());
return orderElement.getOrder().getCode();
}
@Override
@Transactional
public void sendToSubcontractor(SubcontractedTaskData subcontractedTaskData)
throws ValidationException, ConnectionProblemsException,
UnrecoverableErrorServiceException {
subcontractedTaskDataDAO.save(subcontractedTaskData);
subcontractedTaskData.setState(SubcontractState.FAILED_SENT);
if (!subcontractedTaskData.isSendable()) {
throw new RuntimeException("Subcontracted task already sent");
}
if (!subcontractedTaskData.getExternalCompany()
.getInteractsWithApplications()) {
throw new RuntimeException(
"External company has not interaction fields filled");
}
makeSubcontractRequestRequest(subcontractedTaskData);
subcontractedTaskData.setSubcontractCommunicationDate(new Date());
subcontractedTaskData.setState(SubcontractState.SUCCESS_SENT);
}
private void makeSubcontractRequestRequest(
SubcontractedTaskData subcontractedTaskData)
throws ConnectionProblemsException, UnrecoverableErrorServiceException {
SubcontractedTaskDataDTO subcontractedTaskDataDTO = getSubcontractedTaskData(subcontractedTaskData);
ExternalCompany externalCompany = subcontractedTaskData
.getExternalCompany();
WebClient client = WebClient.create(externalCompany.getAppURI());
client.path("ws/rest/subcontract");
Util.addAuthorizationHeader(client, externalCompany
.getOurCompanyLogin(), externalCompany
.getOurCompanyPassword());
try {
InstanceConstraintViolationsListDTO instanceConstraintViolationsListDTO = client
.post(subcontractedTaskDataDTO,
InstanceConstraintViolationsListDTO.class);
List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = instanceConstraintViolationsListDTO.instanceConstraintViolationsList;
if ((instanceConstraintViolationsList != null)
&& (!instanceConstraintViolationsList.isEmpty())) {
String message = "";
for (ConstraintViolationDTO constraintViolationDTO : instanceConstraintViolationsList.get(0).constraintViolations) {
message += constraintViolationDTO.toString() + "\n";
}
throw new UnrecoverableErrorServiceException(message);
}
} catch (WebApplicationException e) {
LOG.error("Problems connecting with subcontractor web service", e);
String message = _("Problems connecting with subcontractor web service");
if (e.getMessage() != null) {
message += ". " + _("Error: {0}", e.getMessage());
}
throw new ConnectionProblemsException(message, e);
}
}
private SubcontractedTaskDataDTO getSubcontractedTaskData(
SubcontractedTaskData subcontractedTaskData) {
return SubcontractedTaskDataConverter.toDTO(getCompanyCode(),
subcontractedTaskData, getOrderElement(subcontractedTaskData));
}
private String getCompanyCode() {
return configurationDAO.getConfiguration().getCompanyCode();
}
private OrderElementDTO getOrderElement(
SubcontractedTaskData subcontractedTaskData) {
OrderElement orderElement = orderElementDAO
.loadOrderAvoidingProxyFor(subcontractedTaskData.getTask()
.getOrderElement());
if (subcontractedTaskData.isNodeWithoutChildrenExported()) {
orderElement = orderElement.calculateOrderLineForSubcontract();
}
return OrderElementConverter.toDTO(orderElement,
getConfiguration(subcontractedTaskData));
}
private ConfigurationOrderElementConverter getConfiguration(
SubcontractedTaskData subcontractedTaskData) {
// Never export criterions and advances to subcontract
boolean isCriterionsExported = false;
boolean isAdvancesExported = false;
return ConfigurationOrderElementConverter.create(subcontractedTaskData
.isLabelsExported(), subcontractedTaskData
.isMaterialAssignmentsExported(), isAdvancesExported,
subcontractedTaskData.isHoursGroupsExported(),
isCriterionsExported);
}
}

View file

@ -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.web.subcontract.exceptions;
/**
* Exception to encapsulate connection problems between the application and a
* web service.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public class ConnectionProblemsException extends Exception {
public ConnectionProblemsException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -0,0 +1,33 @@
/*
* 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.subcontract.exceptions;
/**
* Exception to encapsulate unrecoverable errors returned by a web service.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public class UnrecoverableErrorServiceException extends Exception {
public UnrecoverableErrorServiceException(String message) {
super(message);
}
}

View file

@ -28,6 +28,14 @@ package org.navalplanner.ws.common.impl;
*/
public class ConfigurationOrderElementConverter {
public static ConfigurationOrderElementConverter create(boolean labels,
boolean materialAssignments, boolean advanceMeasurements,
boolean hoursGroups, boolean criterionRequirements) {
return new ConfigurationOrderElementConverter(labels,
materialAssignments, advanceMeasurements, hoursGroups,
criterionRequirements);
}
public static ConfigurationOrderElementConverter all() {
return new ConfigurationOrderElementConverter(true, true, true, true,
true);

View file

@ -23,6 +23,9 @@ package org.navalplanner.ws.common.impl;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.jaxrs.client.WebClient;
/**
* Utilities class related with web service.
*
@ -47,4 +50,16 @@ public class Util {
return stringWriter.toString();
}
public static String getAuthorizationHeader(String username, String password) {
String authorization = Base64Utility.encode((username + ":" + password)
.getBytes());
return "Basic " + authorization;
}
public static void addAuthorizationHeader(WebClient client, String login,
String password) {
String authorizationHeader = getAuthorizationHeader(login, password);
client.header("Authorization", authorizationHeader);
}
}

View file

@ -0,0 +1,46 @@
/*
* 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.ws.subcontract.impl;
import org.navalplanner.business.planner.entities.SubcontractedTaskData;
import org.navalplanner.ws.common.api.OrderElementDTO;
import org.navalplanner.ws.subcontract.api.SubcontractedTaskDataDTO;
/**
* Converter from/to {@link SubcontractedTaskData} entities to/from DTOs.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public final class SubcontractedTaskDataConverter {
private SubcontractedTaskDataConverter() {
}
public final static SubcontractedTaskDataDTO toDTO(String companyCode,
SubcontractedTaskData subcontractedTaskData,
OrderElementDTO orderElementDTO) {
return new SubcontractedTaskDataDTO(companyCode, subcontractedTaskData
.getWorkDescription(), subcontractedTaskData
.getSubcontractPrice(), subcontractedTaskData
.getSubcontractedCode(), orderElementDTO);
}
}

View file

@ -72,8 +72,11 @@
</row>
<row>
<label value="${i18n:_('Application URI')}:" />
<textbox id="appURI"
value="@{controller.company.appURI}" width="500px" />
<hbox>
<textbox id="appURI"
value="@{controller.company.appURI}" width="500px" />
<label value="${i18n:__('Example: {0}', 'http://localhost:8080/navalplanner-webapp/')}" />
</hbox>
</row>
<row>
<label value="${i18n:_('Our company login')}:" />

View file

@ -0,0 +1,58 @@
<!--
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/>.
-->
<?page title="${i18n:_('Subcontracted tasks')}"?>
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/common/layout/template.zul"?>
<?link rel="stylesheet" type="text/css" href="/common/css/navalpro_v01.css"?>
<?link rel="stylesheet" type="text/css" href="/common/css/navalpro_zk.css"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<div self="@{define(content)}">
<window apply="${subcontractedTasksController}"
title="${i18n:_('Subcontracted tasks list')}">
<vbox id="messagesContainer" />
<grid id="listing"
model="@{controller.subcontractedTasks}"
rowRenderer="@{controller.subcontractedTasksRenderer}"
mold="paging" pageSize="10" fixedLayout="true">
<columns>
<column label="${i18n:_('Subcontratation date')}"/>
<column label="${i18n:_('Communication date')}"/>
<column label="${i18n:_('External company')}"/>
<column label="${i18n:_('Order code')}"/>
<column label="${i18n:_('Subcontracted code')}"/>
<column label="${i18n:_('Task name')}"/>
<column label="${i18n:_('Work description')}"/>
<column label="${i18n:_('Budget')}"/>
<column label="${i18n:_('State')}"/>
<column label="${i18n:_('Operations')}" />
</columns>
</grid>
</window>
</div>
</zk>