# HG changeset patch
# User Nono Carballo <nonofce@gmail.com>
# Date 1537890616 14400
#      Tue Sep 25 11:50:16 2018 -0400
# Node ID 3597d2f15ce438c5092baf680f2ef1b5c8fad05a
# Parent  dc33b14bcb0cb7abc990f75f8ceff963cad29b49
Fixes issue 39350: Allows multiple Routing Assignment for BXI-TR ITT

* A new preference was created
* When the preference is set, Storage Bin is a mandatory parameter in Box/Unbox
  operations from Warehouse Operations window.
* Allows create multiple routing assignment for same area from and different
  area to when preference is set.
* Avoids create any algorithm assignment for BXI-TR, BXP-TR and BXO-TR ITT when
  the preference is set.

diff --git a/src-db/database/sourcedata/AD_MESSAGE.xml b/src-db/database/sourcedata/AD_MESSAGE.xml
--- a/src-db/database/sourcedata/AD_MESSAGE.xml
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml
@@ -829,6 +829,18 @@
 <!--350D861712BD49589F034182CC0069F7-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--350D861712BD49589F034182CC0069F7--></AD_MESSAGE>
 
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9--><AD_MESSAGE>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <AD_MESSAGE_ID><![CDATA[37C4BF7B8FDB49BE8C7D63C7900A16C9]]></AD_MESSAGE_ID>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <VALUE><![CDATA[OBAWO_WAssiNotAllowedForBoxUnboxItt]]></VALUE>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <MSGTEXT><![CDATA[Warehouse Algorithm Assignment is not allowed for Box/Unbox ITT when 'Destination Bin is mandatory" preference is set.]]></MSGTEXT>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <MSGTYPE><![CDATA[E]]></MSGTYPE>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <AD_MODULE_ID><![CDATA[E09B68E8080847CF99A3AA62238C7079]]></AD_MODULE_ID>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--37C4BF7B8FDB49BE8C7D63C7900A16C9--></AD_MESSAGE>
+
 <!--3883D9220B944E64939F01350277C522--><AD_MESSAGE>
 <!--3883D9220B944E64939F01350277C522-->  <AD_MESSAGE_ID><![CDATA[3883D9220B944E64939F01350277C522]]></AD_MESSAGE_ID>
 <!--3883D9220B944E64939F01350277C522-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -2425,6 +2437,18 @@
 <!--97CF132C89624ABDAA16A538FD449FA0-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--97CF132C89624ABDAA16A538FD449FA0--></AD_MESSAGE>
 
+<!--97EBB2B2F8D2498C9D79EC077398B47B--><AD_MESSAGE>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <AD_MESSAGE_ID><![CDATA[97EBB2B2F8D2498C9D79EC077398B47B]]></AD_MESSAGE_ID>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <VALUE><![CDATA[OBAWO_MandatoryDestinationBin]]></VALUE>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <MSGTEXT><![CDATA[Destination bin is mandatory.]]></MSGTEXT>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <MSGTYPE><![CDATA[E]]></MSGTYPE>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <AD_MODULE_ID><![CDATA[E09B68E8080847CF99A3AA62238C7079]]></AD_MODULE_ID>
+<!--97EBB2B2F8D2498C9D79EC077398B47B-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--97EBB2B2F8D2498C9D79EC077398B47B--></AD_MESSAGE>
+
 <!--97EE820BA795495BAFF45F51E8D2B527--><AD_MESSAGE>
 <!--97EE820BA795495BAFF45F51E8D2B527-->  <AD_MESSAGE_ID><![CDATA[97EE820BA795495BAFF45F51E8D2B527]]></AD_MESSAGE_ID>
 <!--97EE820BA795495BAFF45F51E8D2B527-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff --git a/src-db/database/sourcedata/AD_REF_LIST.xml b/src-db/database/sourcedata/AD_REF_LIST.xml
--- a/src-db/database/sourcedata/AD_REF_LIST.xml
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml
@@ -568,6 +568,18 @@
 <!--EE74A07F0D944B72B1322FD03AD7DAD8-->  <AD_MODULE_ID><![CDATA[E09B68E8080847CF99A3AA62238C7079]]></AD_MODULE_ID>
 <!--EE74A07F0D944B72B1322FD03AD7DAD8--></AD_REF_LIST>
 
+<!--F17F55D57C974292A0243D6678CDDE72--><AD_REF_LIST>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <AD_REF_LIST_ID><![CDATA[F17F55D57C974292A0243D6678CDDE72]]></AD_REF_LIST_ID>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <VALUE><![CDATA[OBAWO_MandatoryDestinationBin]]></VALUE>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <NAME><![CDATA[Destination Bin is Mandatory]]></NAME>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <DESCRIPTION><![CDATA[States where the destination bin is mandatory, to avoid the system searching for one.]]></DESCRIPTION>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--F17F55D57C974292A0243D6678CDDE72-->  <AD_MODULE_ID><![CDATA[E09B68E8080847CF99A3AA62238C7079]]></AD_MODULE_ID>
+<!--F17F55D57C974292A0243D6678CDDE72--></AD_REF_LIST>
+
 <!--F28E01D9AD274836B9E13D69ABD829B5--><AD_REF_LIST>
 <!--F28E01D9AD274836B9E13D69ABD829B5-->  <AD_REF_LIST_ID><![CDATA[F28E01D9AD274836B9E13D69ABD829B5]]></AD_REF_LIST_ID>
 <!--F28E01D9AD274836B9E13D69ABD829B5-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/InternalRoutingAssiEventObserver.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/InternalRoutingAssiEventObserver.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/InternalRoutingAssiEventObserver.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/InternalRoutingAssiEventObserver.java
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2017 Openbravo S.L.U.
+ * Copyright (C) 2017-2018 Openbravo S.L.U.
  * Licensed under the Openbravo Commercial License version 1.0
  * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
  * or in the legal folder of this module distribution.
@@ -27,6 +27,7 @@
 import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.warehouse.advancedwarehouseoperations.OBAWOInternalRoutingAssi;
 import org.openbravo.warehouse.advancedwarehouseoperations.ittalgorithm.implementation.MoveStockToBin_ITTAlgorithm;
+import org.openbravo.warehouse.advancedwarehouseoperations.utils.Utilities;
 
 /**
  * Checks no duplicated Routing Assignment has been entered by the user. This must be done as an
@@ -137,8 +138,10 @@
   }
 
   private boolean needToCheckAreaTo(OBAWOInternalRoutingAssi targetIRAssi) {
-    // Only Movement ITT Types are allowed to have the same Area From and different Area To
-    return areaFromIsNull(targetIRAssi) || isMovementITT(targetIRAssi);
+    // Only when ITT is Move or "Destination Bin is mandatory" preference is set, is allowed to have
+    // the same Area From and different Area To
+    return areaFromIsNull(targetIRAssi) || isMovementITT(targetIRAssi)
+        || Utilities.isMandatoryDestinationBinPreferenceSet();
   }
 
   private boolean areaFromIsNull(OBAWOInternalRoutingAssi targetIRAssi) {
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/WarehouseAlgorithmEventObserver.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/WarehouseAlgorithmEventObserver.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/WarehouseAlgorithmEventObserver.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/eventobserver/WarehouseAlgorithmEventObserver.java
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2017 Openbravo S.L.U.
+ * Copyright (C) 2017-2018 Openbravo S.L.U.
  * Licensed under the Openbravo Commercial License version 1.0
  * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
  * or in the legal folder of this module distribution.
@@ -32,6 +32,11 @@
 import org.openbravo.warehouse.advancedwarehouseoperations.OBAWOWarehouseAlgorithm;
 import org.openbravo.warehouse.advancedwarehouseoperations.OBAWOWarehouseRuleAssi;
 import org.openbravo.warehouse.advancedwarehouseoperations.OBAWO_InventoryTransactionType;
+import org.openbravo.warehouse.advancedwarehouseoperations.ittalgorithm.implementation.BoxInStorageDetail_ITTAlgorithm;
+import org.openbravo.warehouse.advancedwarehouseoperations.ittalgorithm.implementation.BoxPlannedStorageDetail_ITTAlgorithm;
+import org.openbravo.warehouse.advancedwarehouseoperations.ittalgorithm.implementation.UnboxStorageDetail_ITTAlgorithm;
+import org.openbravo.warehouse.advancedwarehouseoperations.utils.Utilities;
+
 
 /**
  * EventObserver to check no duplicates entered in warehouse algorithm assignment. This is necessary
@@ -51,6 +56,7 @@
     if (!isValidEvent(event)) {
       return;
     }
+    checkIfWarehouseAlgorithmAssignmentIsAllowedForBoxUnboxItt(event);
     checkForDuplicates(event);
   }
 
@@ -58,9 +64,29 @@
     if (!isValidEvent(event)) {
       return;
     }
+    checkIfWarehouseAlgorithmAssignmentIsAllowedForBoxUnboxItt(event);
     checkForDuplicates(event);
   }
 
+  private void checkIfWarehouseAlgorithmAssignmentIsAllowedForBoxUnboxItt(
+      EntityPersistenceEvent event) {
+    OBAWOWarehouseRuleAssi target = (OBAWOWarehouseRuleAssi) event.getTargetInstance();
+    if (Utilities.isMandatoryDestinationBinPreferenceSet() && isBoxOrUnboxItt(target)) {
+      throw new OBException(OBMessageUtils.messageBD("OBAWO_WAssiNotAllowedForBoxUnboxItt"));
+    }
+  }
+
+  private boolean isBoxOrUnboxItt(OBAWOWarehouseRuleAssi target) {
+    String targetInventoryTransactionTypeId = target.getObawoInvTranType().getId();
+    return targetInventoryTransactionTypeId
+        .equals(BoxInStorageDetail_ITTAlgorithm.INVENTORY_TRANSACTION_TYPE_ID)
+        || targetInventoryTransactionTypeId
+            .equals(UnboxStorageDetail_ITTAlgorithm.INVENTORY_TRANSACTION_TYPE_ID)
+        || targetInventoryTransactionTypeId
+            .equals(BoxPlannedStorageDetail_ITTAlgorithm.INVENTORY_TRANSACTION_TYPE_ID);
+  }
+
+
   private void checkForDuplicates(EntityPersistenceEvent event) {
     OBAWOWarehouseRuleAssi target = (OBAWOWarehouseRuleAssi) event.getTargetInstance();
 
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/BoxInPlannedHandler.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/BoxInPlannedHandler.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/BoxInPlannedHandler.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/BoxInPlannedHandler.java
@@ -57,6 +57,7 @@
         refInvTypeId, refInvId, anyOrganizationId);
     addReferencedInventoryToSelectedStorageDetails(selectedStorageDetails, refInv.getId());
 
+    checkForMandatoryDestinationBin(locatorId);
     final OBAWO_BatchOfTasks batchOfTasks = moveStock(userAssignedId, locatorId,
         selectedStorageDetails);
 
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/MoveStockHandler.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/MoveStockHandler.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/MoveStockHandler.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/MoveStockHandler.java
@@ -119,4 +119,16 @@
     }
   }
 
+  /**
+   * Throws an exception if the OBAWO_MandatoryDestinationBin preference is set and destination bin
+   * is null
+   * 
+   * @param locatorId
+   *          The destination bin
+   */
+  protected void checkForMandatoryDestinationBin(String locatorId) {
+    if (Utilities.isMandatoryDestinationBinPreferenceSet() && locatorId == null) {
+      throw new OBException(OBMessageUtils.messageBD("OBAWO_MandatoryDestinationBin"));
+    }
+  }
 }
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/UnboxHandler.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/UnboxHandler.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/UnboxHandler.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/handler/UnboxHandler.java
@@ -41,6 +41,7 @@
     final ParameterMaps parameterMaps = new ParameterMapsMultiLocatorTo(locatorId,
         selectedStorageDetails);
 
+    checkForMandatoryDestinationBin(locatorId);
     return CentralBroker.getNewInstance().doTheStuff(StorageDetail.class,
         parameterMaps.getMapStorageDetails(), getAction(), userAssignedId, null,
         parameterMaps.getExtraParameters());
diff --git a/src/org/openbravo/warehouse/advancedwarehouseoperations/utils/Utilities.java b/src/org/openbravo/warehouse/advancedwarehouseoperations/utils/Utilities.java
--- a/src/org/openbravo/warehouse/advancedwarehouseoperations/utils/Utilities.java
+++ b/src/org/openbravo/warehouse/advancedwarehouseoperations/utils/Utilities.java
@@ -30,8 +30,10 @@
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.dal.service.OBQuery;
+import org.openbravo.erpCommon.businessUtility.Preferences;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.erpCommon.utility.PropertyException;
 import org.openbravo.model.ad.process.ProcessInstance;
 import org.openbravo.model.ad.ui.Process;
 import org.openbravo.model.common.enterprise.Locator;
@@ -462,4 +464,24 @@
         .contains(storageDetail.getOrganization().getId());
   }
 
+  /**
+   * Check if OBAWO_MandatoryDestinationBin preference is set
+   * 
+   * @return true if set, false otherwise
+   */
+  public static boolean isMandatoryDestinationBinPreferenceSet() {
+    boolean destinationBinIsMandatory = false;
+    OBContext.setAdminMode(false);
+    try {
+      destinationBinIsMandatory = "Y".equals(Preferences.getPreferenceValue(
+          "OBAWO_MandatoryDestinationBin", true, OBContext.getOBContext().getCurrentClient(), null,
+          null, null, null));
+    } catch (PropertyException e) {
+      logger.debug("Property OBAWO_MandatoryDestinationBin is not defined");
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+    return destinationBinIsMandatory;
+  }
+
 }
