Average Costing & Landed Cost fixes

This commit is contained in:
armenrz 2007-06-19 12:47:17 +00:00
parent e1fb105ef2
commit fd04f75d8a
5 changed files with 348 additions and 18 deletions

View File

@ -73,10 +73,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -91,6 +98,7 @@ public class MCostDetail extends X_M_CostDetail
return ok;
} // createOrder
/**
* Create New Invoice Cost Detail for AP Invoices.
* Called from Doc_Invoice - for Invoice Adjustments
@ -133,10 +141,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -195,10 +210,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -255,10 +277,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -319,10 +348,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -379,10 +415,17 @@ public class MCostDetail extends X_M_CostDetail
}
else
{
cd.setDeltaAmt(cd.getAmt().subtract(Amt));
cd.setDeltaQty(cd.getQty().subtract(Qty));
// MZ Goodwill
// set deltaAmt=Amt, deltaQty=qty, and set Cost Detail for Amt and Qty
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
// end MZ
else
return true; // nothing to do
}
@ -407,7 +450,7 @@ public class MCostDetail extends X_M_CostDetail
* @param trxName trx
* @return cost detail
*/
private static MCostDetail get (Properties ctx, String whereClause,
public static MCostDetail get (Properties ctx, String whereClause,
int ID, int M_AttributeSetInstance_ID, String trxName)
{
String sql = "SELECT * FROM M_CostDetail WHERE " + whereClause;
@ -766,9 +809,46 @@ public class MCostDetail extends X_M_CostDetail
// if (cost == null)
// cost = new MCost(product, M_ASI_ID,
// as, Org_ID, ce.getM_CostElement_ID());
BigDecimal qty = getQty();
BigDecimal amt = getAmt();
// MZ Goodwill
// reset non Material Cost Element when CurrentQty is ZERO and from Matched Invoice
if (ce.getCostingMethod() != null)
{
if (cost.getCurrentQty().signum() == 0 // CurrentQty is ZERO
&& getC_InvoiceLine_ID() != 0 && !product.isService() // from Matched Invoice
&& ce.getCostingMethod().equals(as.getCostingMethod())) // based on Accounting Schema Costing Method
{
MCostElement[] nce = MCostElement.getNonCostingMethods(this);
for (int i = 0 ; i < nce.length ; i++)
{
MCost ncost = MCost.get(getCtx(), cost.getAD_Client_ID(), cost.getAD_Org_ID(), cost.getM_Product_ID(), cost.getM_CostType_ID(), cost.getC_AcctSchema_ID(), nce[i].getM_CostElement_ID(), cost.getM_AttributeSetInstance_ID());
if (ncost != null)
{
ncost.setCurrentCostPrice(Env.ZERO);
ncost.setCurrentQty(Env.ZERO);
ncost.save();
}
}
}
}
// end MZ
// MZ Goodwill
// used deltaQty and deltaAmt if exist
BigDecimal qty = Env.ZERO;
BigDecimal amt = Env.ZERO;
if (isDelta())
{
qty = getDeltaQty();
amt = getDeltaAmt();
}
else
{
qty = getQty();
amt = getAmt();
}
// end MZ
int precision = as.getCostingPrecision();
BigDecimal price = amt;
if (qty.signum() != 0)
@ -878,7 +958,13 @@ public class MCostDetail extends X_M_CostDetail
}
else if (!ce.isCostingMethod()) // Cost Adjustments
{
BigDecimal cCosts = cost.getCurrentCostPrice().add(amt);
// MZ Goodwill
// Current Cost is using average
BigDecimal cCosts = cost.getCurrentCostPrice().multiply(cost.getCurrentQty()).add(amt);
BigDecimal cQty = cost.getCurrentQty().add(qty);
if (cQty.signum() != 0)
cCosts = cCosts.divide(cQty, precision, BigDecimal.ROUND_HALF_UP);
// end MZ
cost.setCurrentCostPrice(cCosts);
cost.add(amt, qty);
log.finer("Inv - none - " + cost);
@ -982,7 +1068,6 @@ public class MCostDetail extends X_M_CostDetail
log.warning("Unknown Type: " + toString());
return false;
}
return cost.save();
} // process

View File

@ -708,6 +708,12 @@ public class MInvoice extends X_C_Invoice implements DocAction
fromLine.setRef_InvoiceLine_ID(line.getC_InvoiceLine_ID());
fromLine.save(get_TrxName());
}
// MZ Goodwill
// copy the landed cost
line.copyLandedCostFrom(fromLine);
line.allocateLandedCosts();
// end MZ
}
if (fromLines.length != count)
log.log(Level.SEVERE, "Line difference - From=" + fromLines.length + " <> Saved=" + count);

View File

@ -932,6 +932,10 @@ public class MInvoiceLine extends X_C_InvoiceLine
lca.setM_AttributeSetInstance_ID(iol.getM_AttributeSetInstance_ID());
BigDecimal base = iol.getBase(lc.getLandedCostDistribution());
lca.setBase(base);
// MZ Goodwill
// add set Qty from InOutLine
lca.setQty(iol.getMovementQty());
// end MZ
if (base.signum() != 0)
{
double result = getLineNetAmt().multiply(base).doubleValue();
@ -956,6 +960,10 @@ public class MInvoiceLine extends X_C_InvoiceLine
lca.setM_Product_ID(iol.getM_Product_ID());
lca.setM_AttributeSetInstance_ID(iol.getM_AttributeSetInstance_ID());
lca.setAmt(getLineNetAmt());
// MZ Goodwill
// add set Qty from InOutLine
lca.setQty(iol.getMovementQty());
// end MZ
if (lca.save())
return "";
return "Cannot save single line Allocation = " + lc;
@ -1033,6 +1041,10 @@ public class MInvoiceLine extends X_C_InvoiceLine
lca.setM_AttributeSetInstance_ID(iol.getM_AttributeSetInstance_ID());
BigDecimal base = iol.getBase(LandedCostDistribution);
lca.setBase(base);
// MZ Goodwill
// add set Qty from InOutLine
lca.setQty(iol.getMovementQty());
// end MZ
if (base.signum() != 0)
{
double result = getLineNetAmt().multiply(base).doubleValue();
@ -1077,4 +1089,79 @@ public class MInvoiceLine extends X_C_InvoiceLine
}
} // allocateLandedCostRounding
// MZ Goodwill
/**
* Get LandedCost of InvoiceLine
* @param whereClause starting with AND
* @return landedCost
*/
public MLandedCost[] getLandedCost (String whereClause)
{
ArrayList<MLandedCost> list = new ArrayList<MLandedCost>();
String sql = "SELECT * FROM C_LandedCost WHERE C_InvoiceLine_ID=? ";
if (whereClause != null)
sql += whereClause;
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setInt(1, getC_InvoiceLine_ID());
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
MLandedCost lc = new MLandedCost(getCtx(), rs, get_TrxName());
list.add(lc);
}
rs.close();
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
log.log(Level.SEVERE, "getLandedCost", e);
}
finally
{
try
{
if (pstmt != null)
pstmt.close ();
}
catch (Exception e)
{}
pstmt = null;
}
//
MLandedCost[] landedCost = new MLandedCost[list.size()];
list.toArray(landedCost);
return landedCost;
} // getLandedCost
/**
* Copy LandedCost From other InvoiceLine.
* @param otherInvoiceLine invoiceline
* @return number of lines copied
*/
public int copyLandedCostFrom (MInvoiceLine otherInvoiceLine)
{
if (otherInvoiceLine == null)
return 0;
MLandedCost[] fromLandedCosts = otherInvoiceLine.getLandedCost(null);
int count = 0;
for (int i = 0; i < fromLandedCosts.length; i++)
{
MLandedCost landedCost = new MLandedCost (getCtx(), 0, get_TrxName());
MLandedCost fromLandedCost = fromLandedCosts[i];
PO.copyValues (fromLandedCost, landedCost, fromLandedCost.getAD_Client_ID(), fromLandedCost.getAD_Org_ID());
landedCost.setC_InvoiceLine_ID(getC_InvoiceLine_ID());
landedCost.set_ValueNoCheck ("C_LandedCost_ID", I_ZERO); // new
if (landedCost.save(get_TrxName()))
count++;
}
if (fromLandedCosts.length != count)
log.log(Level.SEVERE, "LandedCost difference - From=" + fromLandedCosts.length + " <> Saved=" + count);
return count;
} // copyLinesFrom
// end MZ
} // MInvoiceLine

View File

@ -81,6 +81,53 @@ public class MMatchInv extends X_M_MatchInv
return retValue;
} // get
// MZ Goodwill
/**
* Get Inv Matches for InvoiceLine
* @param ctx context
* @param C_InvoiceLine_ID invoice
* @param trxName transaction
* @return array of matches
*/
public static MMatchInv[] getInvoiceLine (Properties ctx, int C_InvoiceLine_ID, String trxName)
{
if (C_InvoiceLine_ID == 0)
return new MMatchInv[]{};
//
String sql = "SELECT * FROM M_MatchInv WHERE C_InvoiceLine_ID=?";
ArrayList<MMatchInv> list = new ArrayList<MMatchInv>();
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement (sql, trxName);
pstmt.setInt (1, C_InvoiceLine_ID);
ResultSet rs = pstmt.executeQuery ();
while (rs.next ())
list.add (new MMatchInv (ctx, rs, trxName));
rs.close ();
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
s_log.log(Level.SEVERE, sql, e);
}
try
{
if (pstmt != null)
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
}
MMatchInv[] retValue = new MMatchInv[list.size()];
list.toArray (retValue);
return retValue;
} // getInvoiceLine
// end MZ
/**
* Get Inv Matches for InOut
* @param ctx context
@ -360,6 +407,38 @@ public class MMatchInv extends X_M_MatchInv
{
if (success)
{
// MZ Goodwill
// update/delete Cost Detail and recalculate Current Cost
MCostDetail cd = MCostDetail.get (getCtx(), "C_InvoiceLine_ID=? AND M_AttributeSetInstance_ID=?",
getC_InvoiceLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName());
if (cd != null)
{
MInOut receipt = (new MInOutLine(getCtx(),getM_InOutLine_ID(),get_TrxName())).getParent();
BigDecimal qty = getQty();
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
qty = getQty().negate();
//
BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP);
cd.setDeltaAmt(price.multiply(qty.negate()));
cd.setDeltaQty(qty.negate());
cd.setProcessed(false);
//
cd.setAmt(price.multiply(cd.getQty().subtract(qty)));
cd.setQty(cd.getQty().subtract(qty));
if (!cd.isProcessed())
{
MClient client = MClient.get(getCtx(), getAD_Client_ID());
if (client.isCostImmediate())
cd.process();
}
if (cd.getQty().compareTo(Env.ZERO) == 0)
{
cd.setProcessed(false);
cd.delete(true);
}
}
// end MZ
// Get Order and decrease invoices
MInvoiceLine iLine = new MInvoiceLine (getCtx(), getC_InvoiceLine_ID(), get_TrxName());
int C_OrderLine_ID = iLine.getC_OrderLine_ID();

View File

@ -177,6 +177,52 @@ public class MMatchPO extends X_M_MatchPO
return retValue;
} // getInvoice
// MZ Goodwill
/**
* Get PO Matches for OrderLine
* @param ctx context
* @param C_OrderLine_ID order
* @param trxName transaction
* @return array of matches
*/
public static MMatchPO[] getOrderLine (Properties ctx, int C_OrderLine_ID, String trxName)
{
if (C_OrderLine_ID == 0)
return new MMatchPO[]{};
//
String sql = "SELECT * FROM M_MatchPO WHERE C_OrderLine_ID=?";
ArrayList<MMatchPO> list = new ArrayList<MMatchPO>();
PreparedStatement pstmt = null;
try
{
pstmt = DB.prepareStatement (sql, trxName);
pstmt.setInt (1, C_OrderLine_ID);
ResultSet rs = pstmt.executeQuery ();
while (rs.next ())
list.add (new MMatchPO (ctx, rs, trxName));
rs.close ();
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
s_log.log(Level.SEVERE, sql, e);
}
try
{
if (pstmt != null)
pstmt.close ();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
}
MMatchPO[] retValue = new MMatchPO[list.size()];
list.toArray (retValue);
return retValue;
} // getOrderLine
// end MZ
/**
* Find/Create PO(Inv) Match
@ -704,6 +750,33 @@ public class MMatchPO extends X_M_MatchPO
// (Reserved in VMatch and MInOut.completeIt)
if (success && getC_OrderLine_ID() != 0)
{
// MZ Goodwill
// update/delete Cost Detail and recalculate Current Cost
MCostDetail cd = MCostDetail.get (getCtx(), "C_OrderLine_ID=? AND M_AttributeSetInstance_ID=?",
getC_OrderLine_ID(), getM_AttributeSetInstance_ID(), get_TrxName());
if (cd != null)
{
BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP);
cd.setDeltaAmt(price.multiply(getQty().negate()));
cd.setDeltaQty(getQty().negate());
cd.setProcessed(false);
//
cd.setAmt(price.multiply(cd.getQty().subtract(getQty())));
cd.setQty(cd.getQty().subtract(getQty()));
if (!cd.isProcessed())
{
MClient client = MClient.get(getCtx(), getAD_Client_ID());
if (client.isCostImmediate())
cd.process();
}
if (cd.getQty().compareTo(Env.ZERO) == 0)
{
cd.setProcessed(false);
cd.delete(true);
}
}
// end MZ
MOrderLine orderLine = new MOrderLine (getCtx(), getC_OrderLine_ID(), get_TrxName());
if (getM_InOutLine_ID() != 0)
orderLine.setQtyDelivered(orderLine.getQtyDelivered().subtract(getQty()));