details:   https://code.openbravo.com/erp/devel/pi/rev/8af60f70a49c
changeset: 17817:8af60f70a49c
user:      David Miguelez <david.miguelez <at> openbravo.com>
date:      Fri Aug 31 14:30:18 2012 +0200
summary:   Fixes issue 21406: Fixes Costing Rule process to prevent 
transactions without cost.

diffstat:

 
src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.class
 |    0 
 
src-util/modulescript/src/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.java
            |   51 +
 src/org/openbravo/costing/CostingBackground.java                               
                               |   42 +-
 src/org/openbravo/costing/CostingMigrationProcess.java                         
                               |    2 +-
 src/org/openbravo/costing/CostingRuleProcess.java                              
                               |  443 ++++++---
 5 files changed, 373 insertions(+), 165 deletions(-)

diffs (truncated from 735 to 300 lines):

diff -r 4e97236ce97e -r 8af60f70a49c 
src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.class
Binary file 
src-util/modulescript/build/classes/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.class
 has changed
diff -r 4e97236ce97e -r 8af60f70a49c 
src-util/modulescript/src/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.java
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ 
b/src-util/modulescript/src/org/openbravo/modulescript/UpdateCostingRulesWhenNotCalculatedCosts.java
        Fri Aug 31 14:30:18 2012 +0200
@@ -0,0 +1,51 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (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) 2012 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.modulescript;
+
+import java.sql.PreparedStatement;
+
+import org.openbravo.database.ConnectionProvider;
+import org.openbravo.modulescript.ModuleScript;
+
+public class UpdateCostingRulesWhenNotCalculatedCosts extends ModuleScript {
+
+  public void execute() {
+    try {
+      String query = " UPDATE m_costing_rule ";
+      query = query + "SET isvalidated = 'N' ";
+      query = query + "WHERE m_costing_rule_id IN ";
+      query = query + "     (SELECT  m_costing_rule_id ";
+      query = query + "      FROM m_costing_rule cr ";
+      query = query + "        JOIN (SELECT ad_org_id, MIN(datefrom) AS 
startingdate ";
+      query = query + "              FROM m_costing_rule ";
+      query = query + "              GROUP BY ad_org_id) mcr ON cr.ad_org_id = 
mcr.ad_org_id ";
+      query = query + "      WHERE EXISTS ";
+      query = query + "             (SELECT 1 ";
+      query = query + "              FROM m_transaction trx ";
+      query = query + "              WHERE ad_get_org_le_bu(trx.ad_org_id, 
'LE') = cr.ad_org_id ";
+      query = query + "                AND trx.iscostcalculated = 'N' ";
+      query = query + "                AND trxprocessdate < mcr.startingdate)) 
";
+      ConnectionProvider cp = getConnectionProvider();
+      PreparedStatement ps = cp.getPreparedStatement(query);
+      ps.executeUpdate();
+    } catch (Exception e) {
+      handleError(e);
+    }
+  }
+}
diff -r 4e97236ce97e -r 8af60f70a49c 
src/org/openbravo/costing/CostingBackground.java
--- a/src/org/openbravo/costing/CostingBackground.java  Fri Aug 31 08:32:49 
2012 +0200
+++ b/src/org/openbravo/costing/CostingBackground.java  Fri Aug 31 14:30:18 
2012 +0200
@@ -18,6 +18,7 @@
  */
 package org.openbravo.costing;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -29,7 +30,9 @@
 import org.openbravo.dal.service.OBQuery;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.model.common.enterprise.Organization;
 import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.materialmgmt.cost.CostingRule;
 import org.openbravo.model.materialmgmt.transaction.MaterialTransaction;
 import org.openbravo.scheduling.ProcessBundle;
 import org.openbravo.scheduling.ProcessLogger;
@@ -51,7 +54,30 @@
     result.setType("Success");
     result.setTitle(OBMessageUtils.messageBD("Success"));
 
-    List<MaterialTransaction> trxs = getTransactionsBatch();
+    // Get organizations with costing rules.
+    StringBuffer where = new StringBuffer();
+    where.append(" as o");
+    where.append(" where exists (");
+    where.append("    select 1 from " + CostingRule.ENTITY_NAME + " as cr");
+    where.append("    where ad_is_orgincluded(o.id, cr." + 
CostingRule.PROPERTY_ORGANIZATION
+        + ".id, " + CostingRule.PROPERTY_CLIENT + ".id) <> -1 ");
+    where.append("      and cr." + CostingRule.PROPERTY_VALIDATED + " is 
true");
+    where.append(" )");
+    OBQuery<Organization> orgQry = 
OBDal.getInstance().createQuery(Organization.class,
+        where.toString());
+    List<Organization> orgs = orgQry.list();
+    List<String> orgsWithRule = new ArrayList<String>();
+    if (orgs.size() == 0) {
+      log4j.debug("No organizations with Cosrting Rule defiend");
+      logger.logln(OBMessageUtils.messageBD("Success"));
+      bundle.setResult(result);
+      return;
+    }
+    for (Organization org : orgs) {
+      orgsWithRule.add(org.getId());
+    }
+
+    List<MaterialTransaction> trxs = getTransactionsBatch(orgsWithRule);
     int counter = 0, total = trxs.size(), batch = 0;
     boolean pendingTrx = trxs.size() > 0;
     while (pendingTrx && counter < maxTransactions) {
@@ -85,15 +111,15 @@
         SessionHandler.getInstance().commitAndStart();
       }
       OBDal.getInstance().getSession().clear();
-      trxs = getTransactionsBatch();
-      pendingTrx = areTransactionsPending();
+      trxs = getTransactionsBatch(orgsWithRule);
+      pendingTrx = areTransactionsPending(orgsWithRule);
       total += trxs.size();
     }
     logger.logln(OBMessageUtils.messageBD("Success"));
     bundle.setResult(result);
   }
 
-  private List<MaterialTransaction> getTransactionsBatch() {
+  private List<MaterialTransaction> getTransactionsBatch(List<String> 
orgsWithRule) {
     StringBuffer where = new StringBuffer();
     where.append(" as trx");
     where.append(" join trx." + MaterialTransaction.PROPERTY_PRODUCT + " as 
p");
@@ -102,10 +128,13 @@
     where.append("   and p." + Product.PROPERTY_PRODUCTTYPE + " = 'I'");
     where.append("   and p." + Product.PROPERTY_STOCKED + " = true");
     where.append("   and trx." + 
MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE + " <= :now");
+    where.append("   and trx." + MaterialTransaction.PROPERTY_ORGANIZATION + " 
in (:orgs)");
     where.append(" order by trx." + 
MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE);
     OBQuery<MaterialTransaction> trxQry = OBDal.getInstance().createQuery(
         MaterialTransaction.class, where.toString());
     trxQry.setNamedParameter("now", new Date());
+    trxQry.setFilterOnReadableOrganization(false);
+    trxQry.setNamedParameter("orgs", orgsWithRule);
 
     if (maxTransactions == 0) {
       maxTransactions = trxQry.count();
@@ -115,7 +144,7 @@
     return trxQry.list();
   }
 
-  private boolean areTransactionsPending() {
+  private boolean areTransactionsPending(List<String> orgsWithRule) {
     StringBuffer where = new StringBuffer();
     where.append(" as trx");
     where.append(" join trx." + MaterialTransaction.PROPERTY_PRODUCT + " as 
p");
@@ -124,11 +153,14 @@
     where.append("   and p." + Product.PROPERTY_PRODUCTTYPE + " = 'I'");
     where.append("   and p." + Product.PROPERTY_STOCKED + " = true");
     where.append("   and trx." + 
MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE + " <= :now");
+    where.append("   and trx." + MaterialTransaction.PROPERTY_ORGANIZATION + " 
in (:orgs)");
     where.append(" order by trx." + 
MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE);
     OBQuery<MaterialTransaction> trxQry = OBDal.getInstance().createQuery(
         MaterialTransaction.class, where.toString());
     trxQry.setMaxResult(1);
     trxQry.setNamedParameter("now", new Date());
+    trxQry.setFilterOnReadableOrganization(false);
+    trxQry.setNamedParameter("orgs", orgsWithRule);
 
     return trxQry.list().size() > 0;
   }
diff -r 4e97236ce97e -r 8af60f70a49c 
src/org/openbravo/costing/CostingMigrationProcess.java
--- a/src/org/openbravo/costing/CostingMigrationProcess.java    Fri Aug 31 
08:32:49 2012 +0200
+++ b/src/org/openbravo/costing/CostingMigrationProcess.java    Fri Aug 31 
14:30:18 2012 +0200
@@ -350,7 +350,7 @@
         (String) DalUtil.getId(rule.getClient()));
     final Set<String> childOrgs = 
osp.getChildTree(rule.getOrganization().getId(), true);
     CostingRuleProcess crp = new CostingRuleProcess();
-    crp.createCostingRuleInits(rule, childOrgs);
+    crp.createCostingRuleInits(rule.getId(), childOrgs, null);
 
     // Set valid from date
     Date startingDate = new Date();
diff -r 4e97236ce97e -r 8af60f70a49c 
src/org/openbravo/costing/CostingRuleProcess.java
--- a/src/org/openbravo/costing/CostingRuleProcess.java Fri Aug 31 08:32:49 
2012 +0200
+++ b/src/org/openbravo/costing/CostingRuleProcess.java Fri Aug 31 14:30:18 
2012 +0200
@@ -22,15 +22,16 @@
 import java.math.RoundingMode;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.lang.time.DateUtils;
 import org.apache.log4j.Logger;
 import org.hibernate.Query;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.type.DateType;
-import org.hibernate.type.StringType;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.dal.core.DalUtil;
@@ -42,15 +43,18 @@
 import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.financial.FinancialUtils;
 import org.openbravo.materialmgmt.InventoryCountProcess;
-import org.openbravo.model.ad.access.User;
+import org.openbravo.model.ad.system.Client;
 import org.openbravo.model.common.currency.Currency;
 import org.openbravo.model.common.enterprise.Locator;
 import org.openbravo.model.common.enterprise.Organization;
 import org.openbravo.model.common.enterprise.Warehouse;
+import org.openbravo.model.common.plm.AttributeSetInstance;
 import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.common.plm.ProductUOM;
+import org.openbravo.model.common.uom.UOM;
 import org.openbravo.model.materialmgmt.cost.CostingRule;
 import org.openbravo.model.materialmgmt.cost.CostingRuleInit;
-import org.openbravo.model.materialmgmt.onhandquantity.StorageDetail;
+import org.openbravo.model.materialmgmt.cost.TransactionCost;
 import org.openbravo.model.materialmgmt.transaction.InventoryCount;
 import org.openbravo.model.materialmgmt.transaction.InventoryCountLine;
 import org.openbravo.model.materialmgmt.transaction.MaterialTransaction;
@@ -71,8 +75,8 @@
     msg.setTitle(OBMessageUtils.messageBD("Success"));
     try {
       OBContext.setAdminMode(false);
-      final String recordID = (String) 
bundle.getParams().get("M_Costing_Rule_ID");
-      final CostingRule rule = OBDal.getInstance().get(CostingRule.class, 
recordID);
+      final String ruleId = (String) 
bundle.getParams().get("M_Costing_Rule_ID");
+      CostingRule rule = OBDal.getInstance().get(CostingRule.class, ruleId);
 
       OrganizationStructureProvider osp = OBContext.getOBContext()
           .getOrganizationStructureProvider(rule.getClient().getId());
@@ -90,43 +94,34 @@
         // Product configured to have cost not calculated cannot have 
transactions with cost
         // calculated.
         checkNoTrxWithCostCalculated(naturalOrgs, childOrgs);
+        if (rule.getStartingDate() != null) {
+          // First rule of an instance that does not need migration. Old 
transactions costs are not
+          // calculated. They are initialized with ZERO cost.
+          initializeOldTrx(childOrgs, rule.getStartingDate());
+        }
       }
-      // Inventories are only needed if the costing rule is updating a 
previous rule or legacy cost
-      // engine was used.
-      if (existsPreviousRule) {
-        createCostingRuleInits(rule, childOrgs);
-        // Set valid from date
-        Date startingDate = DateUtils.truncate(new Date(), Calendar.SECOND);
-        rule.setStartingDate(startingDate);
-        log4j.debug("setting starting date " + startingDate);
-        OBDal.getInstance().flush();
+      // Inventories are only needed:
+      // - if the costing rule is updating a previous rule
+      // - or legacy cost was never used and the first validated rule has a 
starting date different
+      // than null. If the date is old enough that there are not prior 
transactions no inventories
+      // are created.
+      if (existsPreviousRule || rule.getStartingDate() != null) {
+        Date startingDate = rule.getStartingDate();
+        if (existsPreviousRule) {
+          // Set valid from date
+          startingDate = DateUtils.truncate(new Date(), Calendar.SECOND);
+          rule.setStartingDate(startingDate);
+          log4j.debug("setting starting date " + startingDate);
+          OBDal.getInstance().flush();
+        }
+        createCostingRuleInits(ruleId, childOrgs, startingDate);
 
         // Update cost of inventories and process starting physical 
inventories.
-        for (CostingRuleInit cri : rule.getCostingRuleInitList()) {
-          for (InventoryCountLine icl : cri.getCloseInventory()
-              .getMaterialMgmtInventoryCountLineList()) {
-            MaterialTransaction trx = getInventoryLineTransaction(icl);
-            // Remove 1 second from transaction date to ensure that cost is 
calculated with previous
-            // costing rule.
-            trx.setTransactionProcessDate(DateUtils.addSeconds(startingDate, 
-1));
-            Currency cur = 
FinancialUtils.getLegalEntityCurrency(trx.getOrganization());
-            BigDecimal trxCost = CostingUtils.getTransactionCost(trx, 
startingDate, true, cur);
-            BigDecimal cost = trxCost.divide(trx.getMovementQuantity().abs(), 
cur
-                .getCostingPrecision().intValue(), RoundingMode.HALF_UP);
-
-            trx.setCostCalculated(true);
-            trx.setCostingStatus("CC");
-            trx.setTransactionCost(trxCost);
-            OBDal.getInstance().save(trx);
-            InventoryCountLine initICL = getInitIcl(cri.getInitInventory(), 
icl);
-            initICL.setCost(cost);
-            OBDal.getInstance().save(initICL);
-          }
-          OBDal.getInstance().flush();
-          new InventoryCountProcess().processInventory(cri.getInitInventory());
-        }
+        updateInventoriesCostAndProcessInitInventories(ruleId, startingDate, 
existsPreviousRule);
       }
 
+      // Reload rule after possible session clear.
+      rule = OBDal.getInstance().get(CostingRule.class, ruleId);
       rule.setValidated(true);
       CostingStatus.getInstance().setMigrated();

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Openbravo-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to