/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 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.fulfillment.service.shipment;

import static java.lang.String.format;
import static org.openlmis.fulfillment.domain.Shipment.ROWS_WITH_UNRESOLVED_ORDERABLE;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import lombok.NoArgsConstructor;
import org.apache.commons.csv.CSVRecord;
import org.openlmis.fulfillment.domain.CreationDetails;
import org.openlmis.fulfillment.domain.FileColumn;
import org.openlmis.fulfillment.domain.FileTemplate;
import org.openlmis.fulfillment.domain.Order;
import org.openlmis.fulfillment.domain.Shipment;
import org.openlmis.fulfillment.repository.OrderRepository;
import org.openlmis.fulfillment.repository.ShipmentRepository;
import org.openlmis.fulfillment.service.FulfillmentException;
import org.openlmis.fulfillment.util.DateHelper;
import org.openlmis.fulfillment.util.FileColumnKeyPath;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

@Service
@NoArgsConstructor
public class ShipmentBuilder {

  @Value("${shipment.shippedById}")
  private UUID shippedById;

  @Autowired
  private OrderRepository orderRepository;

  @Autowired
  private ShipmentRepository shipmentRepository;

  @Autowired
  private DateHelper dateHelper;

  @Autowired
  private ShipmentLineItemBuilder lineItemBuilder;

  /**
   * Creates a shipment domain object from parsed shipment csv data.
   */
  public Shipment build(FileTemplate template, List<CSVRecord> lines) {
    if (lines.isEmpty()) {
      throw new FulfillmentException("Parsed data is empty");
    }

    FileColumn orderColumn = getOrderIdentifierColumn(template);

    if (orderColumn == null) {
      throw new FulfillmentException("Template is missing order identifier column.");
    }
    //find the order number
    CSVRecord firstRow = lines.get(0);
    String orderIdentifier = firstRow.get(orderColumn.getPosition());
    Order order = (FileColumnKeyPath.ORDER_CODE.equals(orderColumn.getFileColumnKeyPathEnum()))
        ? orderRepository.findByOrderCode(orderIdentifier) :
        orderRepository.findOne(UUID.fromString(orderIdentifier));

    if (order == null) {
      throw new FulfillmentException(
          format("Order not found with order identifier: %s", orderIdentifier));
    }

    Page<Shipment> shipment = shipmentRepository.findByOrder(order, new PageRequest(0, 100));

    if (shipment.hasContent()) {
      throw new FulfillmentException(
          format("Shipment record for order: %s already exists. ", orderIdentifier));
    }

    ImportedShipmentLineItemData result = lineItemBuilder.build(template, lines);

    Map<String, String> extraData = new HashMap<>();
    extraData.put(ROWS_WITH_UNRESOLVED_ORDERABLE, result.getRowsWithUnresolvedOrderableAsString());
    return new Shipment(order,
        new CreationDetails(shippedById,
            dateHelper.getCurrentDateTimeWithSystemZone()), null, result.getLineItems(), extraData);
  }

  private FileColumn getOrderIdentifierColumn(FileTemplate template) {
    return template
        .getFileColumns().stream()
        .filter(i -> FileColumnKeyPath.ORDER_COLUMN_PATHS
            .contains(i.getFileColumnKeyPathEnum())).findFirst()
        .orElse(null);

  }

}

@@ -900,47 +900,8 @@
 t;%0A%0A
-import static java.lang.String.format;%0A
 impo
@@ -982,16 +982,344 @@
 DERABLE;
+%0Aimport static org.openlmis.fulfillment.i18n.MessageKeys.ERROR_MISSING_REQUIRED_COLUMN;%0Aimport static org.openlmis.fulfillment.i18n.MessageKeys.ORDER_NOT_FOUND;%0Aimport static org.openlmis.fulfillment.i18n.MessageKeys.SHIPMENT_LINE_ITEMS_REQUIRED;%0Aimport static org.openlmis.fulfillment.i18n.MessageKeys.SHIPMENT_ORDER_DUPLICATE;
 %0A%0Aimport
@@ -2870,30 +2870,36 @@
 ion(
-%22Parsed data is empty%22
+SHIPMENT_LINE_ITEMS_REQUIRED
 );%0A 
@@ -3042,53 +3042,59 @@
 ion(
-%22Template is missing order identifier column.
+ERROR_MISSING_REQUIRED_COLUMN, %22Order Code/Order ID
 %22);%0A
@@ -3527,69 +3527,23 @@
 ion(
-%0A          format(%22Order not found with order identifier: %25s%22
+ORDER_NOT_FOUND
 , or
@@ -3548,33 +3548,32 @@
 orderIdentifier)
-)
 ;%0A    %7D%0A%0A    Pag
@@ -3734,74 +3734,32 @@
 ion(
-%0A          format(%22Shipment record for order: %25s already exists. %22
+SHIPMENT_ORDER_DUPLICATE
 , or
@@ -3772,17 +3772,16 @@
 ntifier)
-)
 ;%0A    %7D%0A

Use existing MessageKeys instead of String.format