Created background process to execute the UpdateIsCompletelyInvoiced modulescript logic in batches
authorAaron Calero <aaron.calero@openbravo.com>
Fri, 22 Mar 2019 09:23:17 +0100
changeset 32497 f328756bfc8e
parent 32496 b5f399f8e0b1
child 32498 ed508cf70117
Created background process to execute the UpdateIsCompletelyInvoiced modulescript logic in batches
src-db/database/sourcedata/AD_PREFERENCE.xml
src-db/database/sourcedata/AD_PROCESS.xml
src-db/database/sourcedata/AD_REF_LIST.xml
src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateIsCompletelyInvoiced.class
src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateIsCompletelyInvoicedData.class
src-util/modulescript/src/org/openbravo/modulescript/UpdateIsCompletelyInvoiced.java
src-util/modulescript/src/org/openbravo/modulescript/UpdateIsCompletelyInvoiced_data.xsql
src/org/openbravo/erpCommon/ad_process/UpdateIsCompletelyInvoicedQ1.java
--- a/src-db/database/sourcedata/AD_PREFERENCE.xml	Fri Feb 09 11:32:12 2018 +0100
+++ b/src-db/database/sourcedata/AD_PREFERENCE.xml	Fri Mar 22 09:23:17 2019 +0100
@@ -13,6 +13,17 @@
 <!--68FC679E2B9245AA82B660715375AAFF-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--68FC679E2B9245AA82B660715375AAFF--></AD_PREFERENCE>
 
+<!--7C605012370944939EFBF75D767232CA--><AD_PREFERENCE>
+<!--7C605012370944939EFBF75D767232CA-->  <AD_PREFERENCE_ID><![CDATA[7C605012370944939EFBF75D767232CA]]></AD_PREFERENCE_ID>
+<!--7C605012370944939EFBF75D767232CA-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--7C605012370944939EFBF75D767232CA-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--7C605012370944939EFBF75D767232CA-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--7C605012370944939EFBF75D767232CA-->  <VALUE><![CDATA[500000]]></VALUE>
+<!--7C605012370944939EFBF75D767232CA-->  <PROPERTY><![CDATA[NumberUpdateIsCompletelyInvoiced]]></PROPERTY>
+<!--7C605012370944939EFBF75D767232CA-->  <ISPROPERTYLIST><![CDATA[Y]]></ISPROPERTYLIST>
+<!--7C605012370944939EFBF75D767232CA-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--7C605012370944939EFBF75D767232CA--></AD_PREFERENCE>
+
 <!--9B4A5EB695FDA841E040A8C0E1077381--><AD_PREFERENCE>
 <!--9B4A5EB695FDA841E040A8C0E1077381-->  <AD_PREFERENCE_ID><![CDATA[9B4A5EB695FDA841E040A8C0E1077381]]></AD_PREFERENCE_ID>
 <!--9B4A5EB695FDA841E040A8C0E1077381-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_PROCESS.xml	Fri Feb 09 11:32:12 2018 +0100
+++ b/src-db/database/sourcedata/AD_PROCESS.xml	Fri Mar 22 09:23:17 2019 +0100
@@ -6566,6 +6566,29 @@
 <!--6E1ADD5C8B6B4ACB82237DAA8114451E-->  <ISKILLABLE><![CDATA[N]]></ISKILLABLE>
 <!--6E1ADD5C8B6B4ACB82237DAA8114451E--></AD_PROCESS>
 
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03--><AD_PROCESS>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <AD_PROCESS_ID><![CDATA[6F1F3B9DC5A14B83B12E96C4B301EA03]]></AD_PROCESS_ID>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <VALUE><![CDATA[UpdateIsCompletelyInvoicedQ1]]></VALUE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <NAME><![CDATA[Update Is Completely Invoiced Q1]]></NAME>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ACCESSLEVEL><![CDATA[7]]></ACCESSLEVEL>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISUSERSTARTABLE><![CDATA[N]]></ISUSERSTARTABLE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISREPORT><![CDATA[N]]></ISREPORT>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISDIRECTPRINT><![CDATA[N]]></ISDIRECTPRINT>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <CLASSNAME><![CDATA[org.openbravo.erpCommon.ad_process.UpdateIsCompletelyInvoicedQ1]]></CLASSNAME>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISBACKGROUND><![CDATA[Y]]></ISBACKGROUND>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISJASPER><![CDATA[N]]></ISJASPER>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISEXTERNALSERVICE><![CDATA[N]]></ISEXTERNALSERVICE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <UIPATTERN><![CDATA[M]]></UIPATTERN>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISADVANCEDFEATURE><![CDATA[N]]></ISADVANCEDFEATURE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <PREVENTCONCURRENT><![CDATA[Y]]></PREVENTCONCURRENT>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <IS_EXPLICIT_ACCESS><![CDATA[N]]></IS_EXPLICIT_ACCESS>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03-->  <ISKILLABLE><![CDATA[Y]]></ISKILLABLE>
+<!--6F1F3B9DC5A14B83B12E96C4B301EA03--></AD_PROCESS>
+
 <!--6FBD65B0FDB74D1AB07F0EADF18D48AE--><AD_PROCESS>
 <!--6FBD65B0FDB74D1AB07F0EADF18D48AE-->  <AD_PROCESS_ID><![CDATA[6FBD65B0FDB74D1AB07F0EADF18D48AE]]></AD_PROCESS_ID>
 <!--6FBD65B0FDB74D1AB07F0EADF18D48AE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REF_LIST.xml	Fri Feb 09 11:32:12 2018 +0100
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml	Fri Mar 22 09:23:17 2019 +0100
@@ -8918,6 +8918,17 @@
 <!--3675AC3ABD5B4A79B3E76126C4411871-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--3675AC3ABD5B4A79B3E76126C4411871--></AD_REF_LIST>
 
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502--><AD_REF_LIST>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <AD_REF_LIST_ID><![CDATA[36AE3ECA97C940CBAB62E9E1E2CA4502]]></AD_REF_LIST_ID>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <VALUE><![CDATA[NumberUpdateIsCompletelyInvoiced]]></VALUE>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <NAME><![CDATA[Number of Record to Update is Completely Invoiced]]></NAME>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--36AE3ECA97C940CBAB62E9E1E2CA4502--></AD_REF_LIST>
+
 <!--36BDF2DEFAA240CFB69F066B48CFD9DE--><AD_REF_LIST>
 <!--36BDF2DEFAA240CFB69F066B48CFD9DE-->  <AD_REF_LIST_ID><![CDATA[36BDF2DEFAA240CFB69F066B48CFD9DE]]></AD_REF_LIST_ID>
 <!--36BDF2DEFAA240CFB69F066B48CFD9DE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
Binary file src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateIsCompletelyInvoiced.class has changed
Binary file src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateIsCompletelyInvoicedData.class has changed
--- a/src-util/modulescript/src/org/openbravo/modulescript/UpdateIsCompletelyInvoiced.java	Fri Feb 09 11:32:12 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html
- * Software distributed under the License  is  distributed  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License.
- * The Original Code is Openbravo ERP.
- * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2018 Openbravo SLU
- * All Rights Reserved.
- * Contributor(s):  ______________________________________.
- ************************************************************************
- */
-
-package org.openbravo.modulescript;
-
-import org.apache.log4j.Logger;
-import org.openbravo.database.ConnectionProvider;
-
-/**
- * Updates M_InOut.IsCompletelyInvoiced flag.
- * The IsCompletelyInvoiced checkbox indicates if this document is completely invoiced or not.
- * This flag is used only in sales flow and shown in the Goods Shipment Header.
- */
-public class UpdateIsCompletelyInvoiced extends ModuleScript {
-
-  private static final Logger log4j = Logger.getLogger(UpdateIsCompletelyInvoiced.class);
-
-  @Override
-  public void execute() {
-    try {
-      ConnectionProvider cp = getConnectionProvider();
-      boolean isCompletelyInvoicedUpdated= UpdateIsCompletelyInvoicedData.isCompletelyInvoicedUpdated(cp);
-      if(!isCompletelyInvoicedUpdated) {
-        log4j.info("This moduleScript can take long to finish. Please be patient...");
-        long init = System.currentTimeMillis();
-        int shipmentsUpdated = UpdateIsCompletelyInvoicedData.updateIsCompletelyInvoiced(cp);
-        if (shipmentsUpdated > 0) {
-          log4j.info("Updated " + shipmentsUpdated + " shipments in "+(System.currentTimeMillis() - init)+" ms.");
-        }
-        UpdateIsCompletelyInvoicedData.createPreference(cp);
-      }
-    } catch (Exception e) {
-      handleError(e);
-    }
-  }
-
-  @Override
-  protected ModuleScriptExecutionLimits getModuleScriptExecutionLimits() {
-    return new ModuleScriptExecutionLimits("0", null, new OpenbravoVersion(3, 0, 31775));
-  }
-}
--- a/src-util/modulescript/src/org/openbravo/modulescript/UpdateIsCompletelyInvoiced_data.xsql	Fri Feb 09 11:32:12 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html
- * Software distributed under the License  is  distributed  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License.
- * The Original Code is Openbravo ERP.
- * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2018 Openbravo SLU
- * All Rights Reserved.
- * Contributor(s):  ______________________________________.
- ************************************************************************
--->
-<SqlClass name="UpdateIsCompletelyInvoicedData" package="org.openbravo.modulescript">
-  <SqlMethod name="select" type="preparedStatement" return="multiple">
-    <SqlMethodComment></SqlMethodComment>
-    <Sql>
-      <![CDATA[
-        select 1 as dummy from dual
-      ]]>
-    </Sql>
-  </SqlMethod>
-  <SqlMethod name="updateIsCompletelyInvoiced" type="preparedStatement" return="rowCount">
-    <SqlMethodComment></SqlMethodComment>
-    <Sql>
-     <![CDATA[
-        UPDATE M_InOut
-        SET iscompletelyinvoiced = 'N'
-        WHERE issotrx = 'Y'
-        AND EXISTS (SELECT 1 FROM M_INOUTLINE l
-                        LEFT JOIN c_invoiceline il ON l.m_inoutline_id = il.m_inoutline_id
-                        LEFT JOIN c_invoice i ON il.c_invoice_id = i.c_invoice_id
-                        WHERE l.M_INOUT_ID = M_InOut.M_INOUT_ID
-                        GROUP BY l.m_inoutline_id, l.movementqty
-                        HAVING ( l.movementqty >= 0 AND l.movementqty > Sum(COALESCE(CASE WHEN i.docstatus = 'CO' THEN il.qtyinvoiced ELSE 0 END, 0)) )
-                             OR ( l.movementqty < 0 AND l.movementqty < Sum(COALESCE(CASE WHEN i.docstatus = 'CO' THEN il.qtyinvoiced ELSE 0 END, 0)) ) )
-      ]]>
-    </Sql>
-  </SqlMethod>
-  <SqlMethod name="createPreference" type="preparedStatement" return="rowcount">
-      <SqlMethodComment></SqlMethodComment>
-       <Sql>
-       <![CDATA[
-           INSERT INTO ad_preference (
-           ad_preference_id, ad_client_id, ad_org_id, isactive,
-           createdby, created, updatedby, updated, attribute
-           ) VALUES (
-           get_uuid(), '0', '0', 'Y',
-           '0', NOW(), '0', NOW(), 'UpdateShipmentIsCompletelyInvoiced')
-         ]]>
-        </Sql>
-   </SqlMethod>
-   <SqlMethod name="isCompletelyInvoicedUpdated" type="preparedStatement" return="boolean">
-    <SqlMethodComment></SqlMethodComment>
-    <Sql>
-      <![CDATA[
-        SELECT count(1) as exist
-        FROM DUAL
-        WHERE EXISTS (SELECT 1 
-                      FROM ad_preference
-                      WHERE attribute = 'UpdateShipmentIsCompletelyInvoiced')
-      ]]>
-    </Sql>
-  </SqlMethod>
-</SqlClass>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/ad_process/UpdateIsCompletelyInvoicedQ1.java	Fri Mar 22 09:23:17 2019 +0100
@@ -0,0 +1,164 @@
+/*
+ ************************************************************************************
+ * Copyright (C) 2019 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.
+ ************************************************************************************
+ */
+
+package org.openbravo.erpCommon.ad_process;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.hibernate.Query;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.core.TriggerHandler;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.erpCommon.businessUtility.Preferences;
+import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.scheduling.KillableProcess;
+import org.openbravo.scheduling.ProcessBundle;
+import org.openbravo.scheduling.ProcessLogger;
+import org.openbravo.service.db.DalBaseProcess;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This process updates inOut values for UpdateIsCompletelyInvoiced.
+ *
+ */
+public class UpdateIsCompletelyInvoicedQ1 extends DalBaseProcess implements KillableProcess {
+  private static final int UPDATE_BATCH_SIZE = 1000;
+  private static final int QUERY_SIZE = 100 * UPDATE_BATCH_SIZE;
+  private static int MAX_NUMBER_OF_RECORDS = 500000;
+  private Logger log4j = LoggerFactory.getLogger(this.getClass());
+  private boolean kill = false;
+
+  @Override
+  protected void doExecute(ProcessBundle bundle) throws Exception {
+    final String clientId = bundle.getContext().toVars().getClient();
+    final ProcessLogger logger = bundle.getLogger();
+
+    String numberUpdateIsCompletelyInvoiced = Preferences.getPreferenceValue(
+        "NumberUpdateIsCompletelyInvoiced", true, OBContext.getOBContext().getCurrentClient(),
+        OBContext.getOBContext().getCurrentOrganization(), OBContext.getOBContext().getUser(),
+        OBContext.getOBContext().getRole(), null);
+    try {
+      MAX_NUMBER_OF_RECORDS = Integer.parseInt(numberUpdateIsCompletelyInvoiced);
+    } catch (NumberFormatException ignore) {
+      logger
+          .logln("Preference 'Number of Record to Update is Completely Invoiced' has wrong value: "
+              + numberUpdateIsCompletelyInvoiced);
+      MAX_NUMBER_OF_RECORDS = 500000;
+    }
+    logger.logln("Max Number of Records to Update: " + MAX_NUMBER_OF_RECORDS);
+
+    int numTotalRows = 0;
+    try {
+      numTotalRows = updateInOut(clientId, logger, numTotalRows);
+      logger.logln("Total rows updated: " + numTotalRows);
+      if (kill) {
+        bundle.getLogger().log("Process has finished. It was killed by user.");
+      } else if (numTotalRows < MAX_NUMBER_OF_RECORDS) {
+        logger.logln("No more rows to update");
+      }
+    } catch (Exception e) {
+      OBError result = OBMessageUtils.translateError(e.getMessage());
+      log4j.error(result.getMessage(), e);
+      logger.logln(result.getMessage());
+      bundle.setResult(result);
+      OBDal.getInstance().rollbackAndClose();
+      throw new JobExecutionException(e.getMessage(), e);
+    }
+  }
+
+  private int updateInOut(final String clientId, final ProcessLogger logger, int numTotalRows)
+      throws SQLException {
+    List<String> inOutIdsToUpdate;
+    int finalNumTotalRows = numTotalRows;
+    int rowsUpdated = 0;
+    while (finalNumTotalRows < MAX_NUMBER_OF_RECORDS && !kill
+        && !(inOutIdsToUpdate = getInOutRecordsToUpdate(clientId)).isEmpty()) {
+      rowsUpdated = updateWrongValues(inOutIdsToUpdate);
+      finalNumTotalRows = finalNumTotalRows + rowsUpdated;
+    }
+    return finalNumTotalRows;
+  }
+
+  @SuppressWarnings("unchecked")
+  private List<String> getInOutRecordsToUpdate(final String clientId) {
+    final Query inOutIds = OBDal
+        .getInstance()
+        .getSession()
+        .createQuery( //
+            "SELECT distinct io.id" //
+                + " FROM MaterialMgmtShipmentInOut io" //
+                + " WHERE io.salesTransaction = true" //
+                + " AND io.completelyInvoiced = true" //
+                + " AND EXISTS (SELECT 1" //
+                + "   FROM MaterialMgmtShipmentInOutLine iol" //
+                + "   LEFT JOIN iol.invoiceLineList il" //
+                + "   LEFT JOIN il.invoice i" //
+                + "   WHERE iol.shipmentReceipt = io" //
+                + "   GROUP BY iol.id, iol.movementQuantity" //
+                + "   HAVING (iol.movementQuantity >= 0 AND iol.movementQuantity > SUM(COALESCE(CASE WHEN i.documentStatus = 'CO' THEN il.invoicedQuantity ELSE 0 END,0)))" //
+                + "   OR (iol.movementQuantity < 0 AND iol.movementQuantity < SUM(COALESCE(CASE WHEN i.documentStatus = 'CO' THEN il.invoicedQuantity ELSE 0 END,0))))");
+    inOutIds.setMaxResults(QUERY_SIZE);
+    log4j.info("Executing query to get m_inouts to process");
+    List<String> inOutListIds = inOutIds.list();
+    log4j.info("M_InOuts to update: " + inOutListIds.size());
+    return inOutListIds;
+  }
+
+  private int updateWrongValues(final List<String> inOutIdsToUpdate) throws SQLException {
+    int totalUpdatedRecords = 0;
+    int recordsToUpdate = inOutIdsToUpdate.size();
+    boolean stop = false;
+    try {
+      log4j.info("Starting m_inout update process...");
+      TriggerHandler.getInstance().disable();
+      while (!kill && !stop && totalUpdatedRecords < QUERY_SIZE) {
+        int updatedRecords = 0;
+        List<String> sublist = null;
+        if (totalUpdatedRecords + UPDATE_BATCH_SIZE >= recordsToUpdate) {
+          sublist = inOutIdsToUpdate.subList(totalUpdatedRecords, recordsToUpdate);
+          stop = true;
+        } else {
+          sublist = inOutIdsToUpdate.subList(totalUpdatedRecords, UPDATE_BATCH_SIZE
+              + totalUpdatedRecords);
+        }
+        if (sublist.size() != 0) {
+          final Query inOutIds = OBDal
+              .getInstance()
+              .getSession()
+              .createQuery(
+                  "UPDATE MaterialMgmtShipmentInOut SET completelyInvoiced = 'N' where id in :ids");
+          inOutIds.setParameterList("ids", sublist);
+          updatedRecords = inOutIds.executeUpdate();
+          totalUpdatedRecords = totalUpdatedRecords + updatedRecords;
+          OBDal.getInstance().getConnection().commit();
+          OBDal.getInstance().getSession().clear();
+          log4j.info("Updated " + updatedRecords + " m_inouts. Total updated: "
+              + totalUpdatedRecords + ". ");
+        } else {
+          stop = true;
+        }
+      }
+    } finally {
+      TriggerHandler.getInstance().enable();
+    }
+    return totalUpdatedRecords;
+  }
+
+  @Override
+  public void kill(ProcessBundle processBundle) throws Exception {
+    processBundle.getLogger().log(
+        "Process has been killed by user and will stop when last iteration finishes.");
+    kill = true;
+  }
+
+}