# HG changeset patch
# User Rafa Alonso <ral@openbravo.com>
# Date 1457193873 -3600
#      Sat Mar 05 17:04:33 2016 +0100
# Node ID 71c9788af6b2501ebd3f8577e406d821bfe0d1d2
# Parent  962eab45efce69ff95aed5bf4214c68da6f1c0a3
Related to issue 32415: Patch to reproduce it

diff -r 962eab45efce -r 71c9788af6b2 web/org.openbravo.retail.posterminal/js/data/dataordersave.js
--- a/web/org.openbravo.retail.posterminal/js/data/dataordersave.js	Thu Mar 03 08:00:49 2016 -0600
+++ b/web/org.openbravo.retail.posterminal/js/data/dataordersave.js	Sat Mar 05 17:04:33 2016 +0100
@@ -151,102 +151,104 @@
         // Important: at this point, the receipt is considered final. Nothing must alter it
         var frozenReceipt = new OB.Model.Order();
         OB.UTIL.clone(receipt, frozenReceipt);
-        OB.info("[receipt.closed] Starting transaction. ReceiptId: " + receipt.get('id'));
-        OB.Dal.transaction(function (tx) {
-          receipt.set('hasbeenpaid', 'Y');
-          frozenReceipt.set('hasbeenpaid', 'Y');
-          // when all the properties of the receipt have been set, keep a copy
-          OB.UTIL.cashUpReport(receipt, function () {
-            OB.UTIL.calculateCurrentCash(null, tx);
-            OB.MobileApp.model.updateDocumentSequenceWhenOrderSaved(receipt.get('documentnoSuffix'), receipt.get('quotationnoSuffix'), function () {
-              OB.trace('Saving receipt.');
-              OB.Dal.saveInTransaction(tx, receipt, function () {
-                // the trigger is fired on the receipt object, as there is only 1 that is being updated
-                receipt.trigger('integrityOk'); // Is important for module print last receipt. This module listen trigger.   
-              });
+        console.error("[dev] first ");
+        setTimeout(function () {
+          OB.info("[receipt.closed] Starting transaction. ReceiptId: " + receipt.get('id'));
+          OB.Dal.transaction(function (tx) {
+            receipt.set('hasbeenpaid', 'Y');
+            frozenReceipt.set('hasbeenpaid', 'Y');
+            // when all the properties of the receipt have been set, keep a copy
+            OB.UTIL.cashUpReport(receipt, function () {
+              OB.UTIL.calculateCurrentCash(null, tx);
+              OB.MobileApp.model.updateDocumentSequenceWhenOrderSaved(receipt.get('documentnoSuffix'), receipt.get('quotationnoSuffix'), function () {
+                OB.trace('Saving receipt.');
+                OB.Dal.saveInTransaction(tx, receipt, function () {
+                  // the trigger is fired on the receipt object, as there is only 1 that is being updated
+                  receipt.trigger('integrityOk'); // Is important for module print last receipt. This module listen trigger.   
+                });
+              }, tx);
             }, tx);
-          }, tx);
-        }, function () {
-          // the transaction failed
-          OB.error("[receipt.closed] The transaction failed to be commited. ReceiptId: " + receipt.get('id'));
-          // rollback other changes
-          receipt.set('hasbeenpaid', 'N');
-          frozenReceipt.set('hasbeenpaid', 'N');
-          if (eventParams && eventParams.callback) {
-            eventParams.callback({
-              frozenReceipt: frozenReceipt,
-              isCancelled: false
-            });
-          }
-        }, function () {
-          // success transaction...
-          OB.info("[receipt.closed] Transaction success. ReceiptId: " + receipt.get('id'));
-
-          function serverMessageForQuotation(receipt) {
-            var isLayaway = (receipt.get('orderType') === 2 || receipt.get('isLayaway'));
-            var currentDocNo = receipt.get('documentNo');
-            if (receipt && receipt.get('isQuotation')) {
-              OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_QuotationSaved', [currentDocNo]));
-            } else {
-              if (isLayaway) {
-                OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_MsgLayawaySaved', [currentDocNo]));
-              } else {
-                OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_MsgReceiptSaved', [currentDocNo]));
-              }
-            }
-
-            OB.trace('Order successfully removed.');
-          }
-
-          // create a clone of the receipt to be used when executing the final callback
-          if (OB.UTIL.HookManager.get('OBPOS_PostSyncReceipt')) {
-            // create a clone of the receipt to be used within the hook
-            var receiptForPostSyncReceipt = new OB.Model.Order();
-            OB.UTIL.clone(receipt, receiptForPostSyncReceipt);
-            //If there are elements in the hook, we are forced to execute the callback only after the synchronization process
-            //has been executed, to prevent race conditions with the callback processes (printing and deleting the receipt)
-            OB.trace('Execution Sync process.');
-
-            OB.MobileApp.model.runSyncProcess(function () {
-              OB.UTIL.HookManager.executeHooks('OBPOS_PostSyncReceipt', {
-                receipt: receiptForPostSyncReceipt
-              }, function () {
-                serverMessageForQuotation(receipt);
-                if (eventParams && eventParams.callback) {
-                  eventParams.callback({
-                    frozenReceipt: frozenReceipt,
-                    isCancelled: false
-                  });
-                }
-              });
-            }, function () {
-              OB.UTIL.HookManager.executeHooks('OBPOS_PostSyncReceipt', {
-                receipt: receiptForPostSyncReceipt
-              }, function () {
-                if (eventParams && eventParams.callback) {
-                  eventParams.callback({
-                    frozenReceipt: frozenReceipt,
-                    isCancelled: false
-                  });
-                }
-              });
-            });
-          } else {
-            OB.trace('Execution Sync process.');
-            //If there are no elements in the hook, we can execute the callback asynchronusly with the synchronization process
+          }, function () {
+            // the transaction failed
+            OB.error("[receipt.closed] The transaction failed to be commited. ReceiptId: " + receipt.get('id'));
+            // rollback other changes
+            receipt.set('hasbeenpaid', 'N');
+            frozenReceipt.set('hasbeenpaid', 'N');
             if (eventParams && eventParams.callback) {
               eventParams.callback({
                 frozenReceipt: frozenReceipt,
                 isCancelled: false
               });
             }
-            OB.MobileApp.model.runSyncProcess(function () {
-              serverMessageForQuotation(frozenReceipt);
-              OB.debug("Ticket closed: runSyncProcess executed");
-            });
-          }
-        });
+          }, function () {
+            // success transaction...
+            OB.info("[receipt.closed] Transaction success. ReceiptId: " + receipt.get('id'));
 
+            function serverMessageForQuotation(receipt) {
+              var isLayaway = (receipt.get('orderType') === 2 || receipt.get('isLayaway'));
+              var currentDocNo = receipt.get('documentNo');
+              if (receipt && receipt.get('isQuotation')) {
+                OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_QuotationSaved', [currentDocNo]));
+              } else {
+                if (isLayaway) {
+                  OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_MsgLayawaySaved', [currentDocNo]));
+                } else {
+                  OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_MsgReceiptSaved', [currentDocNo]));
+                }
+              }
+
+              OB.trace('Order successfully removed.');
+            }
+
+            // create a clone of the receipt to be used when executing the final callback
+            if (OB.UTIL.HookManager.get('OBPOS_PostSyncReceipt')) {
+              // create a clone of the receipt to be used within the hook
+              var receiptForPostSyncReceipt = new OB.Model.Order();
+              OB.UTIL.clone(receipt, receiptForPostSyncReceipt);
+              //If there are elements in the hook, we are forced to execute the callback only after the synchronization process
+              //has been executed, to prevent race conditions with the callback processes (printing and deleting the receipt)
+              OB.trace('Execution Sync process.');
+
+              OB.MobileApp.model.runSyncProcess(function () {
+                OB.UTIL.HookManager.executeHooks('OBPOS_PostSyncReceipt', {
+                  receipt: receiptForPostSyncReceipt
+                }, function () {
+                  serverMessageForQuotation(receipt);
+                  if (eventParams && eventParams.callback) {
+                    eventParams.callback({
+                      frozenReceipt: frozenReceipt,
+                      isCancelled: false
+                    });
+                  }
+                });
+              }, function () {
+                OB.UTIL.HookManager.executeHooks('OBPOS_PostSyncReceipt', {
+                  receipt: receiptForPostSyncReceipt
+                }, function () {
+                  if (eventParams && eventParams.callback) {
+                    eventParams.callback({
+                      frozenReceipt: frozenReceipt,
+                      isCancelled: false
+                    });
+                  }
+                });
+              });
+            } else {
+              OB.trace('Execution Sync process.');
+              //If there are no elements in the hook, we can execute the callback asynchronusly with the synchronization process
+              if (eventParams && eventParams.callback) {
+                eventParams.callback({
+                  frozenReceipt: frozenReceipt,
+                  isCancelled: false
+                });
+              }
+              OB.MobileApp.model.runSyncProcess(function () {
+                serverMessageForQuotation(frozenReceipt);
+                OB.debug("Ticket closed: runSyncProcess executed");
+              });
+            }
+          });
+        }, 2000);
       });
     }, this);
 
diff -r 962eab45efce -r 71c9788af6b2 web/org.openbravo.retail.posterminal/js/model/order.js
--- a/web/org.openbravo.retail.posterminal/js/model/order.js	Thu Mar 03 08:00:49 2016 -0600
+++ b/web/org.openbravo.retail.posterminal/js/model/order.js	Sat Mar 05 17:04:33 2016 +0100
@@ -1394,20 +1394,23 @@
               // Display related services after calculate gross, if it is new line and if the line has not been deleted.
               // The line might has been deleted during calculate gross for examples if there was an error in taxes.
               var productId = args.productToAdd.get('forceFilterId') ? args.productToAdd.get('forceFilterId') : args.productToAdd.id;
-              args.receipt._loadRelatedServices(args.productToAdd.get('productType'), productId, args.productToAdd.get('productCategory'), function (data) {
-                if (data) {
-                  if (data.hasservices) {
-                    args.orderline.set('hasRelatedServices', true);
-                    args.orderline.trigger('showServicesButton');
-                  } else {
-                    args.orderline.set('hasRelatedServices', false);
+              setTimeout(function () {
+                console.error("[dev] second ");
+                args.receipt._loadRelatedServices(args.productToAdd.get('productType'), productId, args.productToAdd.get('productCategory'), function (data) {
+                  if (data) {
+                    if (data.hasservices) {
+                      args.orderline.set('hasRelatedServices', true);
+                      args.orderline.trigger('showServicesButton');
+                    } else {
+                      args.orderline.set('hasRelatedServices', false);
+                    }
+                    args.receipt.save();
+                    if (data.hasmandatoryservices) {
+                      args.receipt.trigger('showProductList', args.orderline, 'mandatory');
+                    }
                   }
-                  args.receipt.save();
-                  if (data.hasmandatoryservices) {
-                    args.receipt.trigger('showProductList', args.orderline, 'mandatory');
-                  }
-                }
-              }, args.orderline);
+                }, args.orderline);
+              }, 1000);
             }
           });
           subs.doSubscription();
