details: https://code.openbravo.com/erp/devel/pi/rev/3002c6a4217c changeset: 17447:3002c6a4217c user: Eduardo Argal Guibert <eduardo.argal <at> openbravo.com> date: Wed Jul 11 16:24:37 2012 +0200 summary: Fixes bug 21011
details: https://code.openbravo.com/erp/devel/pi/rev/1860f7606340 changeset: 17448:1860f7606340 user: Eduardo Argal Guibert <eduardo.argal <at> openbravo.com> date: Wed Jul 11 16:31:35 2012 +0200 summary: Fixes bug 21012 details: https://code.openbravo.com/erp/devel/pi/rev/541d869d34e4 changeset: 17449:541d869d34e4 user: Eduardo Argal Guibert <eduardo.argal <at> openbravo.com> date: Wed Jul 11 16:35:48 2012 +0200 summary: Fixes bug 21013 diffstat: src/org/openbravo/costing/AverageAlgorithm.java | 6 +- src/org/openbravo/costing/CostingMigrationProcess.java | 87 ++++++++- src/org/openbravo/costing/CostingUtils.java | 73 ++++++++- src/org/openbravo/erpCommon/ad_forms/DocInOut.java | 11 +- src/org/openbravo/erpCommon/ad_forms/DocInventory.java | 7 - src/org/openbravo/erpCommon/ad_forms/DocLine_Material.java | 3 +- src/org/openbravo/erpCommon/ad_reports/ReportValuationStock_data.xsql | 5 +- src/org/openbravo/erpCommon/ad_reports/ReportValuationStock_legacy_data.xsql | 4 +- 8 files changed, 163 insertions(+), 33 deletions(-) diffs (truncated from 414 to 300 lines): diff -r a53efff1a3c8 -r 541d869d34e4 src/org/openbravo/costing/AverageAlgorithm.java --- a/src/org/openbravo/costing/AverageAlgorithm.java Wed Jul 11 16:10:29 2012 +0200 +++ b/src/org/openbravo/costing/AverageAlgorithm.java Wed Jul 11 16:35:48 2012 +0200 @@ -57,6 +57,8 @@ BigDecimal trxCostWithSign = (transaction.getMovementQuantity().signum() == -1) ? trxCost .negate() : trxCost; BigDecimal newCost = null; + BigDecimal currentValuedStock = CostingUtils.getCurrentValuedStock(transaction.getProduct(), + costOrg, transaction.getTransactionProcessDate(), costDimensions); BigDecimal currentStock = CostingUtils.getCurrentStock(transaction.getProduct(), costOrg, transaction.getTransactionProcessDate(), costDimensions); if (currentCosting == null) { @@ -67,12 +69,10 @@ .getCostingPrecision().intValue(), RoundingMode.HALF_UP); } } else { - BigDecimal newCostAmt = currentCosting.getCost().multiply(currentStock) - .add(trxCostWithSign); + BigDecimal newCostAmt = currentValuedStock.add(trxCostWithSign); BigDecimal newStock = currentStock.add(transaction.getMovementQuantity()); if (newStock.signum() == 0) { // If stock is zero keep current cost. - // FIXME: Cost adjustment is needed if newCostAmt is not zero. newCost = currentCosting.getCost(); } else { newCost = newCostAmt.divide(newStock, costCurrency.getCostingPrecision().intValue(), diff -r a53efff1a3c8 -r 541d869d34e4 src/org/openbravo/costing/CostingMigrationProcess.java --- a/src/org/openbravo/costing/CostingMigrationProcess.java Wed Jul 11 16:10:29 2012 +0200 +++ b/src/org/openbravo/costing/CostingMigrationProcess.java Wed Jul 11 16:35:48 2012 +0200 @@ -27,8 +27,11 @@ import org.apache.commons.lang.time.DateUtils; import org.apache.log4j.Logger; +import org.hibernate.LockOptions; import org.hibernate.Query; import org.hibernate.SQLQuery; +import org.hibernate.ScrollMode; +import org.hibernate.ScrollableResults; import org.hibernate.criterion.Restrictions; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.type.DateType; @@ -97,9 +100,10 @@ try { OBContext.setAdminMode(false); - if (CostingStatus.getInstance().isMigrated()) { - throw new OBException("@CostMigratedInstance@"); - } + /* + * if (CostingStatus.getInstance().isMigrated()) { throw new + * OBException("@CostMigratedInstance@"); } + */ // FIXME: Remove when HQL based inserts are removed. OBDal.getInstance().registerSQLFunction("get_uuid", new StandardSQLFunction("get_uuid", new StringType())); @@ -302,9 +306,11 @@ OrganizationStructureProvider osp = OBContext.getOBContext() .getOrganizationStructureProvider(client.getId()); Currency clientCur = client.getCurrency(); + OBDal.getInstance().getSession().buildLockRequest(LockOptions.NONE).lock(clientCur); log4j.debug("** Processing client: " + client.getIdentifier() + " with currency: " + clientCur.getIdentifier()); for (Organization legalEntity : osp.getLegalEntitiesList()) { + // OBDal.getInstance().refresh(clientCur); Currency orgCur = legalEntity.getCurrency() != null ? legalEntity.getCurrency() : clientCur; log4j.debug("** Processing organization: " + legalEntity.getIdentifier() + " with currency: " + orgCur.getIdentifier()); @@ -331,6 +337,9 @@ legacyCosts = getLegacyCostBatch(legalEntity, naturalTree); } + updateReceiptAndProductionCosts(naturalTree, !conversionNeeded, clientCur + .getStandardPrecision().intValue()); + // If minDate is null there isn't any cost to update. if (!orgCur.getId().equals(clientCur.getId()) && minDate != null) { Organization convOrg = legalEntity; @@ -338,7 +347,7 @@ while (hasTrxToConvert) { log4j.debug("**** HasTrxToConvert "); for (ConversionRate convRate : getConversionRates(convOrg, clientCur, orgCur, minDate, - maxDate)) { + maxDate, client)) { convertTrxLegacyCosts(convRate, orgCur.getStandardPrecision(), naturalTree); } @@ -405,19 +414,21 @@ trx.setTransactionProcessDate(DateUtils.addSeconds(trx.getTransactionProcessDate(), -1)); BigDecimal cost = getLegacyProductCost(trx.getProduct()); - trx.setCostCalculated(true); - trx.setTransactionCost(cost.multiply(trx.getMovementQuantity().abs()).setScale( - orgCurrency.getStandardPrecision().intValue())); - OBDal.getInstance().save(trx); - InventoryCountLine initICL = crp.getInitIcl(cri.getInitInventory(), icl); if (!clientCurrency.getId().equals(orgCurrency.getId())) { cost = FinancialUtils.getConvertedAmount(cost, clientCurrency, orgCurrency, startingDate, rule.getOrganization(), FinancialUtils.PRECISION_COSTING); } + trx.setCostCalculated(true); + trx.setTransactionCost(cost.multiply(trx.getMovementQuantity().abs()).setScale( + orgCurrency.getStandardPrecision().intValue(), BigDecimal.ROUND_HALF_UP)); + OBDal.getInstance().save(trx); + InventoryCountLine initICL = crp.getInitIcl(cri.getInitInventory(), icl); initICL.setCost(cost); OBDal.getInstance().save(initICL); } } + OBDal.getInstance().flush(); + insertTrxCosts(); } private boolean isMigrationFirstPhaseCompleted() { @@ -440,7 +451,7 @@ private List<Costing> getLegacyCostBatch(Organization legalEntity, Set<String> naturalTree) { StringBuffer where = new StringBuffer(); where.append(" as c"); - where.append(" where c." + Costing.PROPERTY_CLIENT + " = :client"); + where.append(" where c." + Costing.PROPERTY_CLIENT + ".id = :client"); where.append(" and exists (select 1 from " + MaterialTransaction.ENTITY_NAME + " as trx"); where.append(" where trx." + MaterialTransaction.PROPERTY_ORGANIZATION + ".id in (:orgs)"); where.append(" and trx." + MaterialTransaction.PROPERTY_TRANSACTIONCOST + " is null"); @@ -458,7 +469,7 @@ OBQuery<Costing> costingQry = OBDal.getInstance().createQuery(Costing.class, where.toString()); costingQry.setFilterOnReadableClients(false); costingQry.setFilterOnReadableOrganization(false); - costingQry.setNamedParameter("client", legalEntity.getClient()); + costingQry.setNamedParameter("client", legalEntity.getClient().getId()); costingQry.setNamedParameter("orgs", naturalTree); costingQry.setMaxResult(1000); return costingQry.list(); @@ -491,6 +502,50 @@ log4j.debug("****** UpdateTrxLegacyCosts updated:" + updated); } + private void updateReceiptAndProductionCosts(Set<String> naturalTree, boolean setIsCalculated, + int standardPrecission) { + log4j.debug("****** updateReceiptAndProductionCosts"); + + StringBuffer where = new StringBuffer(); + where.append(" as trx"); + where.append(" where trx." + MaterialTransaction.PROPERTY_ORGANIZATION + ".id in (:orgs)"); + where.append(" and (exists (select 1 from " + Costing.ENTITY_NAME + " as cr"); + where.append(" where cr." + Costing.PROPERTY_GOODSSHIPMENTLINE + " = trx." + + MaterialTransaction.PROPERTY_GOODSSHIPMENTLINE + ")"); + where.append(" or exists (select 1 from " + Costing.ENTITY_NAME + " cp"); + where.append(" where cp." + Costing.PROPERTY_PRODUCTIONLINE + " = trx." + + MaterialTransaction.PROPERTY_PRODUCTIONLINE + "))"); + + OBQuery<MaterialTransaction> trxQry = OBDal.getInstance().createQuery( + MaterialTransaction.class, where.toString()); + trxQry.setFilterOnReadableClients(false); + trxQry.setFilterOnReadableOrganization(false); + trxQry.setNamedParameter("orgs", naturalTree); + + ScrollableResults trxs = trxQry.scroll(ScrollMode.FORWARD_ONLY); + int i = 0; + while (trxs.next()) { + final MaterialTransaction trx = (MaterialTransaction) trxs.get()[0]; + Costing cost = null; + if (trx.getGoodsShipmentLine() != null) { + cost = trx.getGoodsShipmentLine().getMaterialMgmtCostingList().get(0); + } else { + cost = trx.getProductionLine().getMaterialMgmtCostingList().get(0); + } + if (cost.getPrice().compareTo(cost.getCost()) != 0) { + log4j.debug("blabla"); + } + trx.setCostCalculated(setIsCalculated); + trx.setTransactionCost(cost.getPrice().multiply(trx.getMovementQuantity().abs()) + .setScale(standardPrecission, BigDecimal.ROUND_HALF_UP)); + OBDal.getInstance().save(trx); + + i++; + } + + log4j.debug("****** updateReceiptAndProductionCosts updated"); + } + private boolean hasTrxToConvert(Set<String> naturalTree, Date minDate, Date maxDate) { StringBuffer where = new StringBuffer(); where.append(" as trx"); @@ -512,7 +567,7 @@ } private List<ConversionRate> getConversionRates(Organization organization, Currency fromCur, - Currency toCur, Date minDate, Date maxDate) { + Currency toCur, Date minDate, Date maxDate, Client client) { StringBuffer where = new StringBuffer(); where.append(" as cr"); where.append(" where cr." + ConversionRate.PROPERTY_ORGANIZATION + ".id = :organizationId"); @@ -521,6 +576,7 @@ where.append(" and cr." + ConversionRate.PROPERTY_VALIDFROMDATE + " <= :maxDate"); where.append(" and cr." + ConversionRate.PROPERTY_VALIDTODATE + " >= :minDate"); where.append(" and cr." + ConversionRate.PROPERTY_ACTIVE + " = true"); + where.append(" and cr." + ConversionRate.PROPERTY_CLIENT + ".id = :client"); where.append(" order by cr." + ConversionRate.PROPERTY_VALIDFROMDATE); OBQuery<ConversionRate> convRateQry = OBDal.getInstance().createQuery(ConversionRate.class, @@ -532,6 +588,7 @@ convRateQry.setNamedParameter("toCur", toCur.getId()); convRateQry.setNamedParameter("maxDate", maxDate); convRateQry.setNamedParameter("minDate", minDate); + convRateQry.setNamedParameter("client", client.getId()); return convRateQry.list(); } @@ -645,11 +702,11 @@ insert.append(", t"); insert.append(", t." + MaterialTransaction.PROPERTY_TRANSACTIONCOST); insert.append(", t." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE); - insert.append(" from " + MaterialTransaction.ENTITY_NAME + " as t"); + insert.append(" from " + TransactionCost.ENTITY_NAME + " as tc "); + insert.append(" right join tc." + TransactionCost.PROPERTY_INVENTORYTRANSACTION + " as t"); insert.append(", " + User.ENTITY_NAME + " as u"); insert.append(" where t." + MaterialTransaction.PROPERTY_TRANSACTIONCOST + " is not null"); - insert.append(" and not exists (select 1 from " + TransactionCost.ENTITY_NAME + " as tc"); - insert.append(" where t = tc)"); + insert.append(" and tc.id is null"); insert.append(" and u.id = :user"); Query queryInsert = OBDal.getInstance().getSession().createQuery(insert.toString()); diff -r a53efff1a3c8 -r 541d869d34e4 src/org/openbravo/costing/CostingUtils.java --- a/src/org/openbravo/costing/CostingUtils.java Wed Jul 11 16:10:29 2012 +0200 +++ b/src/org/openbravo/costing/CostingUtils.java Wed Jul 11 16:35:48 2012 +0200 @@ -187,12 +187,40 @@ */ public static Costing getStandardCostDefinition(Product product, Organization org, Date date, HashMap<CostDimension, BaseOBObject> costDimensions, boolean recheckWithoutDimensions) { + Costing stdCost = getStandardCostDefinition(product, org, date, costDimensions, + recheckWithoutDimensions, "STA"); + if (stdCost != null) { + return stdCost; + } else { + // If no cost is found, search valid legacy cost + return getStandardCostDefinition(product, org, date, costDimensions, + recheckWithoutDimensions, "ST"); + } + } + + /** + * Calculates the standard cost definition of a product on the given date and cost dimensions. + * + * @param product + * The Product to get its Standard Cost + * @param date + * The Date to get the Standard Cost + * @param costDimensions + * The cost dimensions to get the Standard Cost if it is defined by some of them. + * @param recheckWithoutDimensions + * boolean flag to force a recall the method to get the Standard Cost at client level if + * no cost is found in the given cost dimensions. + * @return the Standard Cost. Null when no definition is found. + */ + public static Costing getStandardCostDefinition(Product product, Organization org, Date date, + HashMap<CostDimension, BaseOBObject> costDimensions, boolean recheckWithoutDimensions, + String costtype) { // Get cost from M_Costing for given date. OBCriteria<Costing> obcCosting = OBDal.getInstance().createCriteria(Costing.class); obcCosting.add(Restrictions.eq(Costing.PROPERTY_PRODUCT, product)); obcCosting.add(Restrictions.le(Costing.PROPERTY_STARTINGDATE, date)); obcCosting.add(Restrictions.gt(Costing.PROPERTY_ENDINGDATE, date)); - obcCosting.add(Restrictions.eq(Costing.PROPERTY_COSTTYPE, "STA")); + obcCosting.add(Restrictions.eq(Costing.PROPERTY_COSTTYPE, costtype)); obcCosting.add(Restrictions.isNotNull(Costing.PROPERTY_COST)); if (costDimensions.get(CostDimension.Warehouse) != null) { obcCosting.add(Restrictions.eq(Costing.PROPERTY_WAREHOUSE, @@ -261,6 +289,49 @@ return BigDecimal.ZERO; } + /** + * Calculates the stock of the product on the given date and for the given cost dimensions. It + * only takes transactions that have its cost calculated. + */ + public static BigDecimal getCurrentValuedStock(Product product, Organization org, Date date, + HashMap<CostDimension, BaseOBObject> costDimensions) { + // Get child tree of organizations. + Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider() + .getChildTree(org.getId(), true); + + StringBuffer select = new StringBuffer(); + select.append(" select sum(case"); + select.append(" when trx." + MaterialTransaction.PROPERTY_MOVEMENTQUANTITY + + " < 0 then -tc." + TransactionCost.PROPERTY_COST); + select.append(" else tc." + TransactionCost.PROPERTY_COST + " end ) as cost"); + select.append(" from " + TransactionCost.ENTITY_NAME + " as tc"); + select.append(" join tc." + TransactionCost.PROPERTY_INVENTORYTRANSACTION + " as trx"); + select.append(" join trx." + MaterialTransaction.PROPERTY_STORAGEBIN + " as locator"); + select.append(" where trx." + MaterialTransaction.PROPERTY_PRODUCT + ".id = :product"); + select + .append(" and trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE + " <= :date"); + // Include only transactions that have its cost calculated + select.append(" and trx." + MaterialTransaction.PROPERTY_ISCOSTCALCULATED + " = true"); + if (costDimensions.get(CostDimension.Warehouse) != null) { + select.append(" and locator." + Locator.PROPERTY_WAREHOUSE + ".id = :warehouse"); + } + select.append(" and trx." + MaterialTransaction.PROPERTY_ORGANIZATION + ".id in (:orgs)"); + Query trxQry = OBDal.getInstance().getSession().createQuery(select.toString()); + trxQry.setParameter("product", product.getId()); ------------------------------------------------------------------------------ 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
