IDEMPIERE-118 Average Costing: Negative inventory.

This commit is contained in:
Heng Sin Low 2012-03-20 06:23:52 +08:00
parent 8e216841b6
commit 679cf6474c
4 changed files with 71 additions and 6 deletions

View File

@ -0,0 +1,12 @@
-- Mar 19, 2012 8:33:59 PM MYT
-- IDEMPIERE-118 Average Costing: Negative Inventory
UPDATE AD_Column SET ReadOnlyLogic=NULL,Updated=TO_DATE('2012-03-19 20:33:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=13455
;
UPDATE AD_System
SET LastMigrationScriptApplied='826_IDEMPIERE-118.sql'
WHERE LastMigrationScriptApplied<'826_IDEMPIERE-118.sql'
OR LastMigrationScriptApplied IS NULL
;

View File

@ -0,0 +1,10 @@
-- Mar 19, 2012 8:33:59 PM MYT
-- IDEMPIERE-118 Average Costing: Negative Inventory
UPDATE AD_Column SET ReadOnlyLogic=NULL,Updated=TO_DATE('2012-03-19 20:33:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=13455
;
UPDATE AD_System
SET LastMigrationScriptApplied='826_IDEMPIERE-118.sql'
WHERE LastMigrationScriptApplied<'826_IDEMPIERE-118.sql'
OR LastMigrationScriptApplied IS NULL
;

View File

@ -19,6 +19,7 @@ package org.compiere.acct;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -283,6 +284,7 @@ public class DocManager {
trxName = localTrxName; trxName = localTrxName;
} }
Trx trx = Trx.get(trxName, true);
String error = null; String error = null;
try try
{ {
@ -292,12 +294,22 @@ public class DocManager {
Doc doc = Doc.get (as, AD_Table_ID, rs, trxName); Doc doc = Doc.get (as, AD_Table_ID, rs, trxName);
if (doc != null) if (doc != null)
{ {
Savepoint savepoint = trx.setSavepoint(null);
error = doc.post (force, repost); // repost error = doc.post (force, repost); // repost
status = doc.getPostStatus(); status = doc.getPostStatus();
if (error != null && error.trim().length() > 0) if (error != null && error.trim().length() > 0)
{
trx.rollback(savepoint);
break; break;
} }
else else
{
try {
trx.releaseSavepoint(savepoint);
} catch (Exception e) {}
}
}
else
{ {
return "NoDoc"; return "NoDoc";
} }
@ -311,7 +323,6 @@ public class DocManager {
ValueNamePair dbError = CLogger.retrieveError(); ValueNamePair dbError = CLogger.retrieveError();
// log.log(Level.SEVERE, "(doc not saved) ... rolling back"); // log.log(Level.SEVERE, "(doc not saved) ... rolling back");
if (localTrxName != null) { if (localTrxName != null) {
Trx trx = Trx.get(localTrxName, false);
if (trx != null) if (trx != null)
trx.rollback(); trx.rollback();
} }
@ -321,7 +332,6 @@ public class DocManager {
error = "SaveError"; error = "SaveError";
} }
if (localTrxName != null) { if (localTrxName != null) {
Trx trx = Trx.get(localTrxName, false);
if (trx != null) if (trx != null)
trx.commit(); trx.commit();
} }
@ -329,7 +339,6 @@ public class DocManager {
catch (Exception e) catch (Exception e)
{ {
if (localTrxName != null) { if (localTrxName != null) {
Trx trx = Trx.get(localTrxName, false);
if (trx != null) if (trx != null)
trx.rollback(); trx.rollback();
} }
@ -342,7 +351,6 @@ public class DocManager {
{ {
if (localTrxName != null) if (localTrxName != null)
{ {
Trx trx = Trx.get(localTrxName, false);
if (trx != null) if (trx != null)
trx.close(); trx.close();
} }

View File

@ -1441,6 +1441,15 @@ public class MCost extends X_M_Cost
*/ */
public void add (BigDecimal amt, BigDecimal qty) public void add (BigDecimal amt, BigDecimal qty)
{ {
MCostElement costElement = (MCostElement) getM_CostElement();
if (costElement.isAveragePO() || costElement.isAverageInvoice())
{
if (getCurrentQty().add(qty).signum() < 0)
{
throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()+", Trx Qty="+qty
+ ", CostElement="+costElement.getName()+", Schema="+getC_AcctSchema().getName());
}
}
setCumulatedAmt(getCumulatedAmt().add(amt)); setCumulatedAmt(getCumulatedAmt().add(amt));
setCumulatedQty(getCumulatedQty().add(qty)); setCumulatedQty(getCumulatedQty().add(qty));
setCurrentQty(getCurrentQty().add(qty)); setCurrentQty(getCurrentQty().add(qty));
@ -1462,7 +1471,8 @@ public class MCost extends X_M_Cost
if (getCurrentQty().add(qty).signum() < 0) if (getCurrentQty().add(qty).signum() < 0)
{ {
throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()+", Trx Qty="+qty); throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()+", Trx Qty="+qty
+", CostElement="+getM_CostElement().getName()+", Schema="+getC_AcctSchema().getName());
} }
BigDecimal oldSum = getCurrentCostPrice().multiply(getCurrentQty()); BigDecimal oldSum = getCurrentCostPrice().multiply(getCurrentQty());
@ -1616,6 +1626,17 @@ public class MCost extends X_M_Cost
if (getCumulatedQty().signum() != 0) if (getCumulatedQty().signum() != 0)
setCumulatedQty(Env.ZERO); setCumulatedQty(Env.ZERO);
} }
//-ve current qty will break moving average costing
if ((ce.isAveragePO() || ce.isAverageInvoice()) && is_ValueChanged(COLUMNNAME_CurrentQty))
{
if (getCurrentQty().signum() < 0)
{
throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()
+", CostElement="+getM_CostElement().getName()+", Schema="+getC_AcctSchema().getName());
}
}
return true; return true;
} // beforeSave } // beforeSave
@ -1630,6 +1651,20 @@ public class MCost extends X_M_Cost
} // beforeDelete } // beforeDelete
@Override
public void setCurrentQty(BigDecimal CurrentQty) {
MCostElement ce = (MCostElement)getM_CostElement();
if (ce.isAveragePO() || ce.isAverageInvoice())
{
if (CurrentQty.signum() < 0)
{
throw new AverageCostingNegativeQtyException("Product(ID)="+getM_Product_ID()+", Current Qty="+getCurrentQty()+", New Current Qty="+CurrentQty
+", CostElement="+ce.getName()+", Schema="+getC_AcctSchema().getName());
}
}
super.setCurrentQty(CurrentQty);
}
/** /**
* Test * Test
* @param args ignored * @param args ignored