details:   https://code.openbravo.com/erp/devel/pi/rev/079acca81db9
changeset: 32511:079acca81db9
user:      Asier Martirena <asier.martirena <at> openbravo.com>
date:      Tue Jul 04 17:35:43 2017 +0200
summary:   Fixed issue 36267: Services relation are not set in neg. orders 
after C&R and CL

diffstat:

 src/org/openbravo/erpCommon/businessUtility/CancelAndReplaceUtils.java |  146 
++++++++++
 src/org/openbravo/event/ServiceRelationEventHandler.java               |   12 
+-
 2 files changed, 155 insertions(+), 3 deletions(-)

diffs (236 lines):

diff -r 91a5372f6599 -r 079acca81db9 
src/org/openbravo/erpCommon/businessUtility/CancelAndReplaceUtils.java
--- a/src/org/openbravo/erpCommon/businessUtility/CancelAndReplaceUtils.java    
Mon Jul 24 12:44:18 2017 +0200
+++ b/src/org/openbravo/erpCommon/businessUtility/CancelAndReplaceUtils.java    
Tue Jul 04 17:35:43 2017 +0200
@@ -25,8 +25,10 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.LockOptions;
@@ -50,6 +52,7 @@
 import org.openbravo.dal.security.OrganizationStructureProvider;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
+import org.openbravo.dal.service.OBQuery;
 import org.openbravo.erpCommon.ad_forms.AcctServer;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -65,6 +68,7 @@
 import org.openbravo.model.common.order.OrderLine;
 import org.openbravo.model.common.order.OrderLineOffer;
 import org.openbravo.model.common.order.OrderTax;
+import org.openbravo.model.common.order.OrderlineServiceRelation;
 import org.openbravo.model.common.plm.AttributeSetInstance;
 import org.openbravo.model.common.plm.Product;
 import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount;
@@ -93,6 +97,8 @@
   public static final String DOCTYPE_MatShipment = "MMS";
   public static final int PAYMENT_DOCNO_LENGTH = 30;
 
+  private static Map<String, String> linesRelations = new HashMap<>();
+
   /**
    * Process that creates a replacement order in temporary status in order to 
Cancel and Replace an
    * original order
@@ -418,6 +424,8 @@
           inverseOrder = OBDal.getInstance().get(Order.class, inverseOrderId);
         }
       }
+      // Create or update the needed services relations
+      updateServicesRelations(jsonorder, oldOrder, inverseOrder, newOrder, 
replaceOrder);
       // The netting shipment is flaged as processed.
       if (nettingGoodsShipment != null) {
         processShipmentHeader(nettingGoodsShipment);
@@ -582,6 +590,8 @@
       createInverseOrderLineTaxes(oldOrderLine, inverseOrderLine);
     }
 
+    linesRelations.put(oldOrderLine.getId(), inverseOrderLine.getId());
+
     return inverseOrderLine;
   }
 
@@ -827,6 +837,142 @@
   }
 
   /**
+   * Method that creates the relation between products and services for the 
inverse order. Also, if
+   * the old order has or has a relation with a deferred service, this 
relation must be moved to the
+   * new tickets product.
+   * 
+   * @param oldOrder
+   *          The order that have been canceled.
+   * @param inverseOrder
+   *          The order that is canceling the old order.
+   * @param newOrder
+   *          The order that is replacing the old order.
+   * @param replaceOrder
+   *          If true, the process is C&R, otherwise is a CL process.
+   * @throws JSONException
+   */
+  private static void updateServicesRelations(JSONObject jsonorder, Order 
oldOrder,
+      Order inverseOrder, Order newOrder, boolean replaceOrder) throws 
JSONException {
+    final List<String> createdRelations = new ArrayList<>();
+    final List<OrderlineServiceRelation> relationsToRemove = new ArrayList<>();
+    final OBCriteria<OrderLine> oldOrderLineCriteria = 
OBDal.getInstance().createCriteria(
+        OrderLine.class);
+    oldOrderLineCriteria.add(Restrictions.eq(OrderLine.PROPERTY_SALESORDER, 
oldOrder));
+    for (final OrderLine oldOrderLine : oldOrderLineCriteria.list()) {
+      final StringBuffer where = new StringBuffer();
+      where.append(" WHERE (" + 
OrderlineServiceRelation.PROPERTY_SALESORDERLINE
+          + " = :salesorderline");
+      where.append(" OR " + OrderlineServiceRelation.PROPERTY_ORDERLINERELATED
+          + " = :salesorderline)");
+      final OBQuery<OrderlineServiceRelation> serviceRelationQuery = 
OBDal.getInstance()
+          .createQuery(OrderlineServiceRelation.class, where.toString());
+      serviceRelationQuery.setNamedParameter("salesorderline", oldOrderLine);
+      for (final OrderlineServiceRelation serviceRelation : 
serviceRelationQuery.list()) {
+        if (!createdRelations.contains(serviceRelation.getId())) {
+          createdRelations.add(serviceRelation.getId());
+          if 
(linesRelations.containsKey(serviceRelation.getSalesOrderLine().getId())
+              && 
linesRelations.containsKey(serviceRelation.getOrderlineRelated().getId())) {
+            // Create a new relation if is not a deferred service or a product 
with a deferred
+            // service
+            final OrderlineServiceRelation inverseServiceRelation = 
(OrderlineServiceRelation) DalUtil
+                .copy(serviceRelation, false, true);
+            final OrderLine inverseServiceLine = 
OBDal.getInstance().get(OrderLine.class,
+                
linesRelations.get(serviceRelation.getSalesOrderLine().getId()));
+            inverseServiceRelation.setSalesOrderLine(inverseServiceLine);
+            final OrderLine inverseProductLine = 
OBDal.getInstance().get(OrderLine.class,
+                
linesRelations.get(serviceRelation.getOrderlineRelated().getId()));
+            inverseServiceRelation.setOrderlineRelated(inverseProductLine);
+            
inverseServiceRelation.setAmount(inverseServiceRelation.getAmount().negate());
+            
inverseServiceRelation.setQuantity(inverseServiceRelation.getQuantity().negate());
+            OBDal.getInstance().save(inverseServiceRelation);
+          } else {
+            // Is a deferred relation
+            if (replaceOrder) {
+              if 
(linesRelations.containsKey(serviceRelation.getOrderlineRelated().getId())) {
+                // A product is being replaced, so the service relation must 
be removed (the new
+                // relation is added in the new ticket synchronization)
+                OrderLine newOrderLine = null;
+                final OBCriteria<OrderLine> newOrderLineCriteria = 
OBDal.getInstance()
+                    .createCriteria(OrderLine.class);
+                if (jsonorder != null) {
+                  final JSONArray lines = jsonorder.getJSONArray("lines");
+                  for (int i = 0; i < lines.length(); i++) {
+                    final JSONObject line = lines.getJSONObject(i);
+                    if (line.has("linepos")
+                        && (line.getInt("linepos") + 1) * 10 == 
oldOrderLine.getLineNo()) {
+                      
newOrderLineCriteria.add(Restrictions.eq(OrderLine.PROPERTY_SALESORDER,
+                          newOrder));
+                      
newOrderLineCriteria.add(Restrictions.eq(OrderLine.PROPERTY_LINENO,
+                          (long) ((i + 1) * 10)));
+                      newOrderLineCriteria.setMaxResults(1);
+                      newOrderLine = (OrderLine) 
newOrderLineCriteria.uniqueResult();
+                      break;
+                    }
+                  }
+                } else {
+                  
newOrderLineCriteria.add(Restrictions.eq(OrderLine.PROPERTY_REPLACEDORDERLINE,
+                      oldOrderLine));
+                  newOrderLineCriteria.setMaxResults(1);
+                  newOrderLine = (OrderLine) 
newOrderLineCriteria.uniqueResult();
+                }
+                if (newOrderLine != null) {
+                  // The product haven't been removed during the C&R process. 
The relation must be
+                  // moved from the original order to the new order.
+                  serviceRelation.setOrderlineRelated(newOrderLine);
+                  OBDal.getInstance().save(serviceRelation);
+                } else {
+                  // The product have been removed during the C&R process. The 
service relation must
+                  // be removed.
+                  relationsToRemove.add(serviceRelation);
+                }
+              } else {
+                // A deferred service has been replaced (or canceled), so the 
relation must also be
+                // created for the inverse order
+                final OrderLine inverseServiceLine = 
OBDal.getInstance().get(OrderLine.class,
+                    
linesRelations.get(serviceRelation.getSalesOrderLine().getId()));
+                final OrderlineServiceRelation inverseServiceRelation = 
(OrderlineServiceRelation) DalUtil
+                    .copy(serviceRelation, false, true);
+                inverseServiceRelation.setSalesOrderLine(inverseServiceLine);
+                
inverseServiceRelation.setAmount(inverseServiceRelation.getAmount().negate());
+                
inverseServiceRelation.setQuantity(inverseServiceRelation.getQuantity().negate());
+                OBDal.getInstance().save(inverseServiceRelation);
+              }
+            } else {
+              if 
(!linesRelations.containsKey(serviceRelation.getSalesOrderLine().getId())
+                  && 
linesRelations.containsKey(serviceRelation.getOrderlineRelated().getId())
+                  && 
serviceRelation.getOrderlineRelated().getSalesOrder().getId()
+                      .equals(oldOrder.getId())) {
+                // A product with a related delivered service (in the same 
ticket) is being
+                // canceled. The relation between the original product and the 
service must be
+                // removed.
+                relationsToRemove.add(serviceRelation);
+              } else {
+                // The CL has a service that is being canceled, which is 
related to a product in
+                // other ticket (the product is deferred) or to a product that 
have been delivered
+                // in the same ticket. The new cancellation line of this 
service must also be
+                // related to the product.
+                final OrderLine inverseServiceLine = 
OBDal.getInstance().get(OrderLine.class,
+                    
linesRelations.get(serviceRelation.getSalesOrderLine().getId()));
+                final OrderlineServiceRelation inverseServiceRelation = 
(OrderlineServiceRelation) DalUtil
+                    .copy(serviceRelation, false, true);
+                inverseServiceRelation.setSalesOrderLine(inverseServiceLine);
+                
inverseServiceRelation.setAmount(inverseServiceRelation.getAmount().negate());
+                
inverseServiceRelation.setQuantity(inverseServiceRelation.getQuantity().negate());
+                OBDal.getInstance().save(inverseServiceRelation);
+              }
+            }
+          }
+        }
+      }
+    }
+    // Remove the services relation marked to remove
+    for (final OrderlineServiceRelation serviceRelation : relationsToRemove) {
+      OBDal.getInstance().remove(serviceRelation);
+    }
+    linesRelations.clear();
+  }
+
+  /**
    * Method that updates the inventory based on an M_TRANSACTION record.
    * 
    * @param transaction
diff -r 91a5372f6599 -r 079acca81db9 
src/org/openbravo/event/ServiceRelationEventHandler.java
--- a/src/org/openbravo/event/ServiceRelationEventHandler.java  Mon Jul 24 
12:44:18 2017 +0200
+++ b/src/org/openbravo/event/ServiceRelationEventHandler.java  Tue Jul 04 
17:35:43 2017 +0200
@@ -64,7 +64,9 @@
     BigDecimal amount = (BigDecimal) event.getCurrentState(amountProperty);
     BigDecimal quantity = (BigDecimal) event.getCurrentState(quantityProperty);
     OrderLine orderLine = (OrderLine) event.getCurrentState(solProperty);
-    updateOrderLine(orderLine, amount, quantity, BigDecimal.ZERO, 
BigDecimal.ZERO);
+    if (orderLine.getSalesOrder().getCancelledorder() == null) {
+      updateOrderLine(orderLine, amount, quantity, BigDecimal.ZERO, 
BigDecimal.ZERO);
+    }
   }
 
   public void onUpdate(@Observes EntityUpdateEvent event) {
@@ -84,7 +86,9 @@
     BigDecimal oldAmount = (BigDecimal) event.getPreviousState(amountProperty);
     BigDecimal oldQuantity = (BigDecimal) 
event.getPreviousState(quantityProperty);
     OrderLine currentOrderLine = (OrderLine) 
event.getCurrentState(solProperty);
-    updateOrderLine(currentOrderLine, currentAmount, currentQuantity, 
oldAmount, oldQuantity);
+    if (currentOrderLine.getSalesOrder().getCancelledorder() == null) {
+      updateOrderLine(currentOrderLine, currentAmount, currentQuantity, 
oldAmount, oldQuantity);
+    }
   }
 
   public void onDelete(@Observes EntityDeleteEvent event) {
@@ -102,7 +106,9 @@
     BigDecimal oldAmount = (BigDecimal) event.getCurrentState(amountProperty);
     BigDecimal oldQuantity = (BigDecimal) 
event.getCurrentState(quantityProperty);
     OrderLine orderLine = (OrderLine) event.getCurrentState(solProperty);
-    updateOrderLine(orderLine, BigDecimal.ZERO, BigDecimal.ZERO, oldAmount, 
oldQuantity);
+    if (orderLine.getSalesOrder().getCancelledorder() == null) {
+      updateOrderLine(orderLine, BigDecimal.ZERO, BigDecimal.ZERO, oldAmount, 
oldQuantity);
+    }
   }
 
   private void updateOrderLine(OrderLine currentOrderLine, BigDecimal 
currentAmount,

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openbravo-commits mailing list
Openbravo-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to