Average Costing & Landed Cost fixes
This commit is contained in:
parent
e1fb105ef2
commit
fd04f75d8a
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Reference in New Issue