/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright © 2013 VillageReach * * 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.  For additional information contact info@OpenLMIS.org.  */ package org.openlmis.order.helper; import org.apache.commons.collections.Predicate; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.lang.StringEscapeUtils; import org.openlmis.core.service.ConfigurationSettingService; import org.openlmis.order.domain.Order; import org.openlmis.order.domain.OrderFileColumn; import org.openlmis.order.dto.OrderFileTemplateDTO; import org.openlmis.rnr.domain.LineItemComparator; import org.openlmis.rnr.domain.RnrLineItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.IOException; import java.io.Writer; import java.util.Collections; import java.util.Date; import java.util.List; import static org.apache.commons.collections.CollectionUtils.filter; import static org.joda.time.format.DateTimeFormat.forPattern; /** * OrderCsvHelper provides helper methods to generate a csv file for Order entity. */ @Component public class OrderCsvHelper { public static final String STRING = "string"; public static final String LINE_NO = "line_no"; public static final String ORDER = "order"; private String lineSeparator = "\r\n"; private Boolean encloseValuesWithQuotes = false; @Autowired ConfigurationSettingService configSettingService; public OrderCsvHelper() { } public void writeCsvFile(Order order, OrderFileTemplateDTO orderFileTemplateDTO, Writer writer) throws IOException { List<OrderFileColumn> orderFileColumns = orderFileTemplateDTO.getOrderFileColumns(); removeExcludedColumns(orderFileColumns); if (orderFileTemplateDTO.getOrderConfiguration().isHeaderInFile()) { writeHeader(orderFileColumns, writer); } List<RnrLineItem> nonFullSupplyLineItems = order.getRnr().getNonFullSupplyLineItems(); Collections.sort(nonFullSupplyLineItems, new LineItemComparator()); writeLineItems(order, order.getRnr().getFullSupplyLineItems(), orderFileColumns, writer); writeLineItems(order, nonFullSupplyLineItems, orderFileColumns, writer); } private void removeExcludedColumns(List<OrderFileColumn> orderFileColumns) { filter(orderFileColumns, new Predicate() { @Override public boolean evaluate(Object o) { return ((OrderFileColumn) o).getIncludeInOrderFile(); } }); } private void writeHeader(List<OrderFileColumn> orderFileColumns, Writer writer) throws IOException { for (OrderFileColumn column : orderFileColumns) { String columnLabel = column.getColumnLabel(); if (columnLabel == null) columnLabel = ""; writer.write(columnLabel); if (orderFileColumns.indexOf(column) == (orderFileColumns.size() - 1)) { writer.write(lineSeparator); break; } writer.write(","); } } private void writeLineItems(Order order, List<RnrLineItem> fullSupplyLineItems, List<OrderFileColumn> orderFileColumns, Writer writer) throws IOException { // allow the user to control what line separator to use from the administrative pages // this value was different between a windows and linux target systems. // this could have been written better. lineSeparator = StringEscapeUtils.unescapeJava(configSettingService.getConfigurationStringValue("CSV_LINE_SEPARATOR")); // setting to enclose or not to enclose values in quotes. encloseValuesWithQuotes = configSettingService.getBoolValue("CSV_APPLY_QUOTES"); int counter = 1; for (RnrLineItem rnrLineItem : fullSupplyLineItems) { writeCsvLineItem(order, rnrLineItem, orderFileColumns, writer, counter++); writer.write(lineSeparator); } } private void writeCsvLineItem(Order order, RnrLineItem rnrLineItem, List<OrderFileColumn> orderFileColumns, Writer writer, int counter) throws IOException { JXPathContext orderContext = JXPathContext.newContext(order); JXPathContext lineItemContext = JXPathContext.newContext(rnrLineItem); for (OrderFileColumn orderFileColumn : orderFileColumns) { if (orderFileColumn.getNested() == null || orderFileColumn.getNested().isEmpty()) { writeValue(writer, ""); writeSeparator(orderFileColumns, writer, orderFileColumn); continue; } Object columnValue = getColumnValue(counter, orderContext, lineItemContext, orderFileColumn); if (columnValue instanceof Date) { columnValue = forPattern(orderFileColumn.getFormat()).print(((Date) columnValue).getTime()); } writeValue(writer, columnValue); writeSeparator(orderFileColumns, writer, orderFileColumn); } } private void writeSeparator(List<OrderFileColumn> orderFileColumns, Writer writer, OrderFileColumn orderFileColumn) throws IOException { if (orderFileColumns.indexOf(orderFileColumn) < orderFileColumns.size() - 1) { writer.write(","); } } private void writeValue(Writer writer, Object columnValue) throws IOException { if (encloseValuesWithQuotes) { writer.write("\"" + (columnValue).toString() + "\""); } else { writer.write((columnValue).toString()); } } private Object getColumnValue(int counter, JXPathContext orderContext, JXPathContext lineItemContext, OrderFileColumn orderFileColumn) { Object columnValue; switch (orderFileColumn.getNested()) { case STRING: columnValue = orderFileColumn.getKeyPath(); break; case LINE_NO: columnValue = counter; break; case ORDER: columnValue = orderContext.getValue(orderFileColumn.getKeyPath()); break; default: columnValue = lineItemContext.getValue(orderFileColumn.getKeyPath()); break; } return columnValue; } }