IDEMPIERE-209 Costing: clean up reversal code.
IDEMPIERE-210 Costing: Revert [ 1693997 ] Calculation of cost should happen when transaction complete.
This commit is contained in:
parent
5e34da0a81
commit
b2a9801ed3
|
@ -163,23 +163,34 @@ public class Doc_InOut extends Doc
|
||||||
{
|
{
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
// MZ Goodwill
|
BigDecimal costs = null;
|
||||||
// if Shipment CostDetail exist then get Cost from Cost Detail
|
if (!isReversal(line))
|
||||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?");
|
|
||||||
// end MZ
|
|
||||||
if (costs == null || costs.signum() == 0) // zero costs OK
|
|
||||||
{
|
{
|
||||||
MProduct product = line.getProduct();
|
// MZ Goodwill
|
||||||
if (product.isStocked())
|
// if Shipment CostDetail exist then get Cost from Cost Detail
|
||||||
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?");
|
||||||
|
|
||||||
|
// end MZ
|
||||||
|
if (costs == null || costs.signum() == 0) // zero costs OK
|
||||||
{
|
{
|
||||||
p_Error = "No Costs for " + line.getProduct().getName();
|
MProduct product = line.getProduct();
|
||||||
log.log(Level.WARNING, p_Error);
|
if (product.isStocked())
|
||||||
return null;
|
{
|
||||||
|
p_Error = "No Costs for " + line.getProduct().getName();
|
||||||
|
log.log(Level.WARNING, p_Error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else // ignore service
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else // ignore service
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//temp to avoid NPE
|
||||||
|
costs = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
// CoGS DR
|
// CoGS DR
|
||||||
dr = fact.createLine(line,
|
dr = fact.createLine(line,
|
||||||
line.getAccount(ProductCost.ACCTTYPE_P_Cogs, as),
|
line.getAccount(ProductCost.ACCTTYPE_P_Cogs, as),
|
||||||
|
@ -195,8 +206,8 @@ public class Doc_InOut extends Doc
|
||||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||||
dr.setAD_Org_ID(line.getOrder_Org_ID()); // Revenue X-Org
|
dr.setAD_Org_ID(line.getOrder_Org_ID()); // Revenue X-Org
|
||||||
dr.setQty(line.getQty().negate());
|
dr.setQty(line.getQty().negate());
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed)
|
|
||||||
&& m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Shipment/Receipt
|
// Set AmtAcctDr from Original Shipment/Receipt
|
||||||
if (!dr.updateReverseLine (MInOut.Table_ID,
|
if (!dr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -220,8 +231,8 @@ public class Doc_InOut extends Doc
|
||||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
cr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
cr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
||||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed)
|
|
||||||
&& m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Shipment/Receipt
|
// Set AmtAcctCr from Original Shipment/Receipt
|
||||||
if (!cr.updateReverseLine (MInOut.Table_ID,
|
if (!cr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -235,11 +246,15 @@ public class Doc_InOut extends Doc
|
||||||
//
|
//
|
||||||
if (line.getM_Product_ID() != 0)
|
if (line.getM_Product_ID() != 0)
|
||||||
{
|
{
|
||||||
MCostDetail.createShipment(as, line.getAD_Org_ID(),
|
if (!MCostDetail.createShipment(as, line.getAD_Org_ID(),
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs, line.getQty(),
|
costs, line.getQty(),
|
||||||
line.getDescription(), true, getTrxName());
|
line.getDescription(), true, getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // for all lines
|
} // for all lines
|
||||||
updateProductInfo(as.getC_AcctSchema_ID()); // only for SO!
|
updateProductInfo(as.getC_AcctSchema_ID()); // only for SO!
|
||||||
|
@ -264,22 +279,30 @@ public class Doc_InOut extends Doc
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
// MZ Goodwill
|
BigDecimal costs = null;
|
||||||
// if Shipment CostDetail exist then get Cost from Cost Detail
|
if (!isReversal(line))
|
||||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?");
|
|
||||||
// end MZ
|
|
||||||
|
|
||||||
if (costs == null || costs.signum() == 0) // zero costs OK
|
|
||||||
{
|
{
|
||||||
MProduct product = line.getProduct();
|
// MZ Goodwill
|
||||||
if (product.isStocked())
|
// if Shipment CostDetail exist then get Cost from Cost Detail
|
||||||
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?");
|
||||||
|
// end MZ
|
||||||
|
|
||||||
|
if (costs == null || costs.signum() == 0) // zero costs OK
|
||||||
{
|
{
|
||||||
p_Error = "No Costs for " + line.getProduct().getName();
|
MProduct product = line.getProduct();
|
||||||
log.log(Level.WARNING, p_Error);
|
if (product.isStocked())
|
||||||
return null;
|
{
|
||||||
|
p_Error = "No Costs for " + line.getProduct().getName();
|
||||||
|
log.log(Level.WARNING, p_Error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else // ignore service
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else // ignore service
|
}
|
||||||
continue;
|
else
|
||||||
|
{
|
||||||
|
costs = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
// Inventory DR
|
// Inventory DR
|
||||||
dr = fact.createLine(line,
|
dr = fact.createLine(line,
|
||||||
|
@ -294,8 +317,7 @@ public class Doc_InOut extends Doc
|
||||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
dr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
dr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
||||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed)
|
if (isReversal(line))
|
||||||
&& m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Shipment/Receipt
|
// Set AmtAcctDr from Original Shipment/Receipt
|
||||||
if (!dr.updateReverseLine (MInOut.Table_ID,
|
if (!dr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -309,11 +331,15 @@ public class Doc_InOut extends Doc
|
||||||
//
|
//
|
||||||
if (line.getM_Product_ID() != 0)
|
if (line.getM_Product_ID() != 0)
|
||||||
{
|
{
|
||||||
MCostDetail.createShipment(as, line.getAD_Org_ID(),
|
if (!MCostDetail.createShipment(as, line.getAD_Org_ID(),
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs, line.getQty(),
|
costs, line.getQty(),
|
||||||
line.getDescription(), true, getTrxName());
|
line.getDescription(), true, getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CoGS CR
|
// CoGS CR
|
||||||
|
@ -331,8 +357,7 @@ public class Doc_InOut extends Doc
|
||||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||||
cr.setAD_Org_ID(line.getOrder_Org_ID()); // Revenue X-Org
|
cr.setAD_Org_ID(line.getOrder_Org_ID()); // Revenue X-Org
|
||||||
cr.setQty(line.getQty().negate());
|
cr.setQty(line.getQty().negate());
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed)
|
if (isReversal(line))
|
||||||
&& m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Shipment/Receipt
|
// Set AmtAcctCr from Original Shipment/Receipt
|
||||||
if (!cr.updateReverseLine (MInOut.Table_ID,
|
if (!cr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -357,48 +382,55 @@ public class Doc_InOut extends Doc
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
BigDecimal costs = null;
|
BigDecimal costs = null;
|
||||||
MProduct product = line.getProduct();
|
MProduct product = line.getProduct();
|
||||||
//get costing method for product
|
if (!isReversal(line))
|
||||||
String costingMethod = product.getCostingMethod(as);
|
|
||||||
if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) ||
|
|
||||||
MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) )
|
|
||||||
{
|
{
|
||||||
int C_OrderLine_ID = line.getC_OrderLine_ID();
|
//get costing method for product
|
||||||
// Low - check if c_orderline_id is valid
|
String costingMethod = product.getCostingMethod(as);
|
||||||
if (C_OrderLine_ID > 0)
|
if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) ||
|
||||||
|
MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) )
|
||||||
{
|
{
|
||||||
MOrderLine orderLine = new MOrderLine (getCtx(), C_OrderLine_ID, getTrxName());
|
int C_OrderLine_ID = line.getC_OrderLine_ID();
|
||||||
// Elaine 2008/06/26
|
// Low - check if c_orderline_id is valid
|
||||||
C_Currency_ID = orderLine.getC_Currency_ID();
|
if (C_OrderLine_ID > 0)
|
||||||
//
|
{
|
||||||
costs = orderLine.getPriceCost();
|
MOrderLine orderLine = new MOrderLine (getCtx(), C_OrderLine_ID, getTrxName());
|
||||||
if (costs == null || costs.signum() == 0)
|
// Elaine 2008/06/26
|
||||||
{
|
C_Currency_ID = orderLine.getC_Currency_ID();
|
||||||
costs = orderLine.getPriceActual();
|
//
|
||||||
// Goodwill: Correct included Tax
|
costs = orderLine.getPriceCost();
|
||||||
int C_Tax_ID = orderLine.getC_Tax_ID();
|
if (costs == null || costs.signum() == 0)
|
||||||
if (orderLine.isTaxIncluded() && C_Tax_ID != 0)
|
{
|
||||||
{
|
costs = orderLine.getPriceActual();
|
||||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
// Goodwill: Correct included Tax
|
||||||
if (!tax.isZeroTax())
|
int C_Tax_ID = orderLine.getC_Tax_ID();
|
||||||
|
if (orderLine.isTaxIncluded() && C_Tax_ID != 0)
|
||||||
{
|
{
|
||||||
int stdPrecision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
if (!tax.isZeroTax())
|
||||||
log.fine("Costs=" + costs + " - Tax=" + costTax);
|
{
|
||||||
costs = costs.subtract(costTax);
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
|
||||||
}
|
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
||||||
} // correct included Tax
|
log.fine("Costs=" + costs + " - Tax=" + costTax);
|
||||||
}
|
costs = costs.subtract(costTax);
|
||||||
costs = costs.multiply(line.getQty());
|
}
|
||||||
}
|
} // correct included Tax
|
||||||
else
|
}
|
||||||
{
|
costs = costs.multiply(line.getQty());
|
||||||
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
}
|
||||||
}
|
else
|
||||||
//
|
{
|
||||||
}
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
||||||
|
}
|
||||||
|
//
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
costs = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
if (costs == null || costs.signum() == 0)
|
if (costs == null || costs.signum() == 0)
|
||||||
{
|
{
|
||||||
|
@ -434,7 +466,7 @@ public class Doc_InOut extends Doc
|
||||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||||
dr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
dr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Shipment/Receipt
|
// Set AmtAcctDr from Original Shipment/Receipt
|
||||||
if (!dr.updateReverseLine (MInOut.Table_ID,
|
if (!dr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -464,7 +496,7 @@ public class Doc_InOut extends Doc
|
||||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||||
cr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
cr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||||
cr.setQty(line.getQty().negate());
|
cr.setQty(line.getQty().negate());
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Shipment/Receipt
|
// Set AmtAcctCr from Original Shipment/Receipt
|
||||||
if (!cr.updateReverseLine (MInOut.Table_ID,
|
if (!cr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -487,34 +519,19 @@ public class Doc_InOut extends Doc
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
BigDecimal costs = null;
|
BigDecimal costs = null;
|
||||||
MProduct product = line.getProduct();
|
MProduct product = line.getProduct();
|
||||||
/*
|
if (!isReversal(line))
|
||||||
* BF: [ 2048984 ] Purchase Return costing logic
|
|
||||||
//get costing method for product
|
|
||||||
String costingMethod = product.getCostingMethod(as);
|
|
||||||
if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) ||
|
|
||||||
MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) )
|
|
||||||
{
|
{
|
||||||
int C_OrderLine_ID = line.getC_OrderLine_ID();
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
||||||
MOrderLine orderLine = new MOrderLine (getCtx(), C_OrderLine_ID, getTrxName());
|
|
||||||
costs = orderLine.getPriceCost();
|
|
||||||
if (costs == null || costs.signum() == 0)
|
if (costs == null || costs.signum() == 0)
|
||||||
costs = orderLine.getPriceActual();
|
{
|
||||||
costs = costs.multiply(line.getQty());
|
p_Error = "Resubmit - No Costs for " + product.getName();
|
||||||
// Elaine 2008/06/26
|
log.log(Level.WARNING, p_Error);
|
||||||
C_Currency_ID = orderLine.getC_Currency_ID();
|
return null;
|
||||||
//
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
costs = BigDecimal.ZERO;
|
||||||
}
|
|
||||||
*/
|
|
||||||
costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs
|
|
||||||
if (costs == null || costs.signum() == 0)
|
|
||||||
{
|
|
||||||
p_Error = "Resubmit - No Costs for " + product.getName();
|
|
||||||
log.log(Level.WARNING, p_Error);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
// NotInvoicedReceipt DR
|
// NotInvoicedReceipt DR
|
||||||
// Elaine 2008/06/26
|
// Elaine 2008/06/26
|
||||||
|
@ -535,7 +552,7 @@ public class Doc_InOut extends Doc
|
||||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||||
dr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
dr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||||
dr.setQty(line.getQty().negate());
|
dr.setQty(line.getQty().negate());
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Shipment/Receipt
|
// Set AmtAcctDr from Original Shipment/Receipt
|
||||||
if (!dr.updateReverseLine (MInOut.Table_ID,
|
if (!dr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -565,7 +582,7 @@ public class Doc_InOut extends Doc
|
||||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||||
cr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
cr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||||
if (m_DocStatus.equals(MInOut.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Shipment/Receipt
|
// Set AmtAcctCr from Original Shipment/Receipt
|
||||||
if (!cr.updateReverseLine (MInOut.Table_ID,
|
if (!cr.updateReverseLine (MInOut.Table_ID,
|
||||||
|
@ -588,6 +605,11 @@ public class Doc_InOut extends Doc
|
||||||
return facts;
|
return facts;
|
||||||
} // createFact
|
} // createFact
|
||||||
|
|
||||||
|
private boolean isReversal(DocLine line) {
|
||||||
|
return m_DocStatus.equals(MInOut.DOCSTATUS_Reversed)
|
||||||
|
&& m_Reversal_ID !=0 && line.getReversalLine_ID() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Sales Order Costing Product Info (old).
|
* Update Sales Order Costing Product Info (old).
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import org.compiere.model.MAccount;
|
import org.compiere.model.MAccount;
|
||||||
import org.compiere.model.MAcctSchema;
|
import org.compiere.model.MAcctSchema;
|
||||||
|
import org.compiere.model.MCostDetail;
|
||||||
import org.compiere.model.MInventory;
|
import org.compiere.model.MInventory;
|
||||||
import org.compiere.model.MInventoryLine;
|
import org.compiere.model.MInventoryLine;
|
||||||
import org.compiere.model.ProductCost;
|
import org.compiere.model.ProductCost;
|
||||||
|
@ -147,14 +148,22 @@ public class Doc_Inventory extends Doc
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
// MZ Goodwill
|
BigDecimal costs = null;
|
||||||
// if Physical Inventory CostDetail is exist then get Cost from Cost Detail
|
if (!isReversal(line))
|
||||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?");
|
|
||||||
// end MZ
|
|
||||||
if (costs == null || costs.signum() == 0)
|
|
||||||
{
|
{
|
||||||
p_Error = "No Costs for " + line.getProduct().getName();
|
// MZ Goodwill
|
||||||
return null;
|
// if Physical Inventory CostDetail is exist then get Cost from Cost Detail
|
||||||
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?");
|
||||||
|
// end MZ
|
||||||
|
if (costs == null || costs.signum() == 0)
|
||||||
|
{
|
||||||
|
p_Error = "No Costs for " + line.getProduct().getName();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
costs = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
// Inventory DR CR
|
// Inventory DR CR
|
||||||
dr = fact.createLine(line,
|
dr = fact.createLine(line,
|
||||||
|
@ -164,7 +173,7 @@ public class Doc_Inventory extends Doc
|
||||||
if (dr == null)
|
if (dr == null)
|
||||||
continue;
|
continue;
|
||||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
if (m_DocStatus.equals(MInventory.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Phys.Inventory
|
// Set AmtAcctDr from Original Phys.Inventory
|
||||||
if (!dr.updateReverseLine (MInventory.Table_ID,
|
if (!dr.updateReverseLine (MInventory.Table_ID,
|
||||||
|
@ -178,9 +187,7 @@ public class Doc_Inventory extends Doc
|
||||||
// InventoryDiff DR CR
|
// InventoryDiff DR CR
|
||||||
// or Charge
|
// or Charge
|
||||||
MAccount invDiff = null;
|
MAccount invDiff = null;
|
||||||
if (m_DocStatus.equals(MInventory.DOCSTATUS_Reversed)
|
if (isReversal(line)
|
||||||
&& m_Reversal_ID != 0
|
|
||||||
&& line.getReversalLine_ID() != 0
|
|
||||||
&& line.getC_Charge_ID() != 0) {
|
&& line.getC_Charge_ID() != 0) {
|
||||||
invDiff = line.getChargeAccount(as, costs);
|
invDiff = line.getChargeAccount(as, costs);
|
||||||
} else {
|
} else {
|
||||||
|
@ -198,7 +205,7 @@ public class Doc_Inventory extends Doc
|
||||||
if (line.getC_Charge_ID() != 0) // explicit overwrite for charge
|
if (line.getC_Charge_ID() != 0) // explicit overwrite for charge
|
||||||
cr.setAD_Org_ID(line.getAD_Org_ID());
|
cr.setAD_Org_ID(line.getAD_Org_ID());
|
||||||
|
|
||||||
if (m_DocStatus.equals(MInventory.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Phys.Inventory
|
// Set AmtAcctCr from Original Phys.Inventory
|
||||||
if (!cr.updateReverseLine (MInventory.Table_ID,
|
if (!cr.updateReverseLine (MInventory.Table_ID,
|
||||||
|
@ -211,12 +218,15 @@ public class Doc_Inventory extends Doc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cost Detail
|
// Cost Detail
|
||||||
/* Source move to MInventory.createCostDetail()
|
if (!MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
||||||
MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs, line.getQty(),
|
costs, line.getQty(),
|
||||||
line.getDescription(), getTrxName());*/
|
line.getDescription(), getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||||
|
@ -224,4 +234,8 @@ public class Doc_Inventory extends Doc
|
||||||
return facts;
|
return facts;
|
||||||
} // createFact
|
} // createFact
|
||||||
|
|
||||||
|
private boolean isReversal(DocLine line) {
|
||||||
|
return m_DocStatus.equals(MInventory.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // Doc_Inventory
|
} // Doc_Inventory
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.compiere.model.MAccount;
|
||||||
import org.compiere.model.MAcctSchema;
|
import org.compiere.model.MAcctSchema;
|
||||||
import org.compiere.model.MAcctSchemaElement;
|
import org.compiere.model.MAcctSchemaElement;
|
||||||
import org.compiere.model.MConversionRate;
|
import org.compiere.model.MConversionRate;
|
||||||
|
import org.compiere.model.MCostDetail;
|
||||||
import org.compiere.model.MInOut;
|
import org.compiere.model.MInOut;
|
||||||
import org.compiere.model.MInOutLine;
|
import org.compiere.model.MInOutLine;
|
||||||
import org.compiere.model.MInvoice;
|
import org.compiere.model.MInvoice;
|
||||||
|
@ -305,55 +306,13 @@ public class Doc_MatchInv extends Doc
|
||||||
}
|
}
|
||||||
log.fine("IPV=" + ipv + "; Balance=" + fact.getSourceBalance());
|
log.fine("IPV=" + ipv + "; Balance=" + fact.getSourceBalance());
|
||||||
|
|
||||||
// Elaine 2008/6/20
|
String error = createMatchInvCostDetail(as);
|
||||||
/* Source move to MInvoice.createMatchInvCostDetail()
|
if (error != null && error.trim().length() > 0)
|
||||||
// Cost Detail Record - data from Expense/IncClearing (CR) record
|
|
||||||
// MZ Goodwill
|
|
||||||
// Create Cost Detail Matched Invoice using Total Amount and Total Qty based on InvoiceLine
|
|
||||||
MMatchInv[] mInv = MMatchInv.getInvoiceLine(getCtx(), m_invoiceLine.getC_InvoiceLine_ID(), getTrxName());
|
|
||||||
BigDecimal tQty = Env.ZERO;
|
|
||||||
BigDecimal tAmt = Env.ZERO;
|
|
||||||
for (int i = 0 ; i < mInv.length ; i++)
|
|
||||||
{
|
{
|
||||||
if (mInv[i].isPosted() && mInv[i].getM_MatchInv_ID() != get_ID())
|
p_Error = error;
|
||||||
{
|
return null;
|
||||||
tQty = tQty.add(mInv[i].getQty());
|
|
||||||
multiplier = mInv[i].getQty()
|
|
||||||
.divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP).abs();
|
|
||||||
tAmt = tAmt.add(m_invoiceLine.getLineNetAmt().multiply(multiplier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tAmt = tAmt.add(cr.getAcctBalance().negate()); //Invoice Price
|
|
||||||
|
|
||||||
// Different currency
|
|
||||||
MInvoice invoice = m_invoiceLine.getParent();
|
|
||||||
if (as.getC_Currency_ID() != invoice.getC_Currency_ID())
|
|
||||||
{
|
|
||||||
tAmt = MConversionRate.convert(getCtx(), tAmt,
|
|
||||||
invoice.getC_Currency_ID(), as.getC_Currency_ID(),
|
|
||||||
invoice.getDateAcct(), invoice.getC_ConversionType_ID(),
|
|
||||||
invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
|
|
||||||
if (tAmt == null)
|
|
||||||
{
|
|
||||||
p_Error = "AP Invoice not convertible - " + as.getName();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set Qty to negative value when MovementType is Vendor Returns
|
|
||||||
MInOut receipt = m_receiptLine.getParent();
|
|
||||||
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
|
|
||||||
tQty = tQty.add(getQty().negate()); // Qty is set to negative value
|
|
||||||
else
|
|
||||||
tQty = tQty.add(getQty());
|
|
||||||
|
|
||||||
// Set Total Amount and Total Quantity from Matched Invoice
|
|
||||||
MCostDetail.createInvoice(as, getAD_Org_ID(),
|
|
||||||
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(),
|
|
||||||
m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
|
|
||||||
tAmt, tQty, getDescription(), getTrxName());
|
|
||||||
// end MZ
|
|
||||||
*/
|
|
||||||
// Update Costing
|
// Update Costing
|
||||||
updateProductInfo(as.getC_AcctSchema_ID(),
|
updateProductInfo(as.getC_AcctSchema_ID(),
|
||||||
MAcctSchema.COSTINGMETHOD_StandardCosting.equals(as.getCostingMethod()));
|
MAcctSchema.COSTINGMETHOD_StandardCosting.equals(as.getCostingMethod()));
|
||||||
|
@ -390,6 +349,74 @@ public class Doc_MatchInv extends Doc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Elaine 2008/6/20
|
||||||
|
private String createMatchInvCostDetail(MAcctSchema as)
|
||||||
|
{
|
||||||
|
if (m_invoiceLine != null && m_invoiceLine.get_ID() > 0
|
||||||
|
&& m_receiptLine != null && m_receiptLine.get_ID() > 0)
|
||||||
|
{
|
||||||
|
BigDecimal LineNetAmt = m_invoiceLine.getLineNetAmt();
|
||||||
|
BigDecimal multiplier = getQty()
|
||||||
|
.divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP)
|
||||||
|
.abs();
|
||||||
|
if (multiplier.compareTo(Env.ONE) != 0)
|
||||||
|
LineNetAmt = LineNetAmt.multiply(multiplier);
|
||||||
|
|
||||||
|
// Source from Doc_MatchInv.createFacts(MAcctSchema)
|
||||||
|
// Cost Detail Record - data from Expense/IncClearing (CR) record
|
||||||
|
// MZ Goodwill
|
||||||
|
// Create Cost Detail Matched Invoice using Total Amount and Total Qty based on InvoiceLine
|
||||||
|
MMatchInv[] mInv = MMatchInv.getInvoiceLine(getCtx(), m_invoiceLine.getC_InvoiceLine_ID(), getTrxName());
|
||||||
|
BigDecimal tQty = Env.ZERO;
|
||||||
|
BigDecimal tAmt = Env.ZERO;
|
||||||
|
for (int i = 0 ; i < mInv.length ; i++)
|
||||||
|
{
|
||||||
|
if (mInv[i].isPosted() && mInv[i].getM_MatchInv_ID() != get_ID())
|
||||||
|
{
|
||||||
|
tQty = tQty.add(mInv[i].getQty());
|
||||||
|
multiplier = mInv[i].getQty()
|
||||||
|
.divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP).abs();
|
||||||
|
tAmt = tAmt.add(m_invoiceLine.getLineNetAmt().multiply(multiplier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tAmt = tAmt.add(LineNetAmt); //Invoice Price
|
||||||
|
|
||||||
|
// Different currency
|
||||||
|
MInvoice invoice = m_invoiceLine.getParent();
|
||||||
|
if (as.getC_Currency_ID() != invoice.getC_Currency_ID())
|
||||||
|
{
|
||||||
|
tAmt = MConversionRate.convert(getCtx(), tAmt,
|
||||||
|
invoice.getC_Currency_ID(), as.getC_Currency_ID(),
|
||||||
|
invoice.getDateAcct(), invoice.getC_ConversionType_ID(),
|
||||||
|
invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
|
||||||
|
if (tAmt == null)
|
||||||
|
{
|
||||||
|
return "AP Invoice not convertible - " + as.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set Qty to negative value when MovementType is Vendor Returns
|
||||||
|
MInOut receipt = m_receiptLine.getParent();
|
||||||
|
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
|
||||||
|
tQty = tQty.add(getQty().negate()); // Qty is set to negative value
|
||||||
|
else
|
||||||
|
tQty = tQty.add(getQty());
|
||||||
|
|
||||||
|
MMatchInv matchInv = (MMatchInv)getPO();
|
||||||
|
// Set Total Amount and Total Quantity from Matched Invoice
|
||||||
|
if (!MCostDetail.createInvoice(as, getAD_Org_ID(),
|
||||||
|
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(),
|
||||||
|
m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
|
||||||
|
tAmt, tQty, getDescription(), getTrxName()))
|
||||||
|
{
|
||||||
|
return "Failed to create cost detail record";
|
||||||
|
}
|
||||||
|
// end MZ
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Product Info (old).
|
* Update Product Info (old).
|
||||||
* - Costing (CostStandardCumQty, CostStandardCumAmt, CostAverageCumQty, CostAverageCumAmt)
|
* - Costing (CostStandardCumQty, CostStandardCumAmt, CostAverageCumQty, CostAverageCumAmt)
|
||||||
|
|
|
@ -26,12 +26,15 @@ import org.compiere.model.MAccount;
|
||||||
import org.compiere.model.MAcctSchema;
|
import org.compiere.model.MAcctSchema;
|
||||||
import org.compiere.model.MAcctSchemaElement;
|
import org.compiere.model.MAcctSchemaElement;
|
||||||
import org.compiere.model.MConversionRate;
|
import org.compiere.model.MConversionRate;
|
||||||
|
import org.compiere.model.MCostDetail;
|
||||||
|
import org.compiere.model.MCurrency;
|
||||||
import org.compiere.model.MInOut;
|
import org.compiere.model.MInOut;
|
||||||
import org.compiere.model.MInOutLine;
|
import org.compiere.model.MInOutLine;
|
||||||
import org.compiere.model.MMatchPO;
|
import org.compiere.model.MMatchPO;
|
||||||
import org.compiere.model.MOrder;
|
import org.compiere.model.MOrder;
|
||||||
import org.compiere.model.MOrderLine;
|
import org.compiere.model.MOrderLine;
|
||||||
import org.compiere.model.MProduct;
|
import org.compiere.model.MProduct;
|
||||||
|
import org.compiere.model.MTax;
|
||||||
import org.compiere.model.ProductCost;
|
import org.compiere.model.ProductCost;
|
||||||
import org.compiere.model.X_M_InOut;
|
import org.compiere.model.X_M_InOut;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
|
@ -64,6 +67,7 @@ public class Doc_MatchPO extends Doc
|
||||||
//
|
//
|
||||||
private int m_M_InOutLine_ID = 0;
|
private int m_M_InOutLine_ID = 0;
|
||||||
private MInOutLine m_ioLine = null;
|
private MInOutLine m_ioLine = null;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private int m_C_InvoiceLine_ID = 0;
|
private int m_C_InvoiceLine_ID = 0;
|
||||||
|
|
||||||
private ProductCost m_pc;
|
private ProductCost m_pc;
|
||||||
|
@ -167,6 +171,13 @@ public class Doc_MatchPO extends Doc
|
||||||
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String costingError = createMatchPOCostDetail(as);
|
||||||
|
if (costingError != null && costingError.trim().length() > 0)
|
||||||
|
{
|
||||||
|
p_Error = costingError;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate PPV for standard costing
|
// Calculate PPV for standard costing
|
||||||
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
||||||
String costingMethod = product.getCostingMethod(as);
|
String costingMethod = product.getCostingMethod(as);
|
||||||
|
@ -305,5 +316,100 @@ public class Doc_MatchPO extends Doc
|
||||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||||
log.fine("M_Product_Costing - Updated=" + no);
|
log.fine("M_Product_Costing - Updated=" + no);
|
||||||
} // updateProductInfo
|
} // updateProductInfo
|
||||||
|
|
||||||
|
// Elaine 2008/6/20
|
||||||
|
private String createMatchPOCostDetail(MAcctSchema as)
|
||||||
|
{
|
||||||
|
if (m_ioLine != null && m_ioLine.getM_InOutLine_ID() > 0 &&
|
||||||
|
m_oLine != null && m_oLine.getC_OrderLine_ID() > 0)
|
||||||
|
{
|
||||||
|
MMatchPO mMatchPO = (MMatchPO) getPO();
|
||||||
|
|
||||||
|
// Purchase Order Line
|
||||||
|
BigDecimal poCost = m_oLine.getPriceCost();
|
||||||
|
if (poCost == null || poCost.signum() == 0)
|
||||||
|
{
|
||||||
|
poCost = m_oLine.getPriceActual();
|
||||||
|
// Goodwill: Correct included Tax
|
||||||
|
int C_Tax_ID = m_oLine.getC_Tax_ID();
|
||||||
|
if (m_oLine.isTaxIncluded() && C_Tax_ID != 0)
|
||||||
|
{
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
|
if (!tax.isZeroTax())
|
||||||
|
{
|
||||||
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), m_oLine.getC_Currency_ID());
|
||||||
|
BigDecimal costTax = tax.calculateTax(poCost, true, stdPrecision);
|
||||||
|
log.fine("Costs=" + poCost + " - Tax=" + costTax);
|
||||||
|
poCost = poCost.subtract(costTax);
|
||||||
|
}
|
||||||
|
} // correct included Tax
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source from Doc_MatchPO.createFacts(MAcctSchema)
|
||||||
|
MInOut inOut = m_ioLine.getParent();
|
||||||
|
boolean isReturnTrx = inOut.getMovementType().equals(X_M_InOut.MOVEMENTTYPE_VendorReturns);
|
||||||
|
|
||||||
|
// Create PO Cost Detail Record first
|
||||||
|
// MZ Goodwill
|
||||||
|
// Create Cost Detail Matched PO using Total Amount and Total Qty based on OrderLine
|
||||||
|
MMatchPO[] mPO = MMatchPO.getOrderLine(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName());
|
||||||
|
BigDecimal tQty = Env.ZERO;
|
||||||
|
BigDecimal tAmt = Env.ZERO;
|
||||||
|
for (int i = 0 ; i < mPO.length ; i++)
|
||||||
|
{
|
||||||
|
if (mPO[i].getM_AttributeSetInstance_ID() == mMatchPO.getM_AttributeSetInstance_ID()
|
||||||
|
&& mPO[i].getM_MatchPO_ID() != mMatchPO.getM_MatchPO_ID())
|
||||||
|
{
|
||||||
|
BigDecimal qty = (isReturnTrx ? mPO[i].getQty().negate() : mPO[i].getQty());
|
||||||
|
tQty = tQty.add(qty);
|
||||||
|
tAmt = tAmt.add(poCost.multiply(qty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poCost = poCost.multiply(getQty()); // Delivered so far
|
||||||
|
tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost);
|
||||||
|
tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty());
|
||||||
|
|
||||||
|
// Different currency
|
||||||
|
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
|
||||||
|
{
|
||||||
|
MOrder order = m_oLine.getParent();
|
||||||
|
Timestamp dateAcct = order.getDateAcct();
|
||||||
|
//get costing method for product
|
||||||
|
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
||||||
|
String costingMethod = product.getCostingMethod(as);
|
||||||
|
if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) ||
|
||||||
|
MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) )
|
||||||
|
dateAcct = inOut.getDateAcct(); //Movement Date
|
||||||
|
//
|
||||||
|
BigDecimal rate = MConversionRate.getRate(
|
||||||
|
order.getC_Currency_ID(), as.getC_Currency_ID(),
|
||||||
|
dateAcct, order.getC_ConversionType_ID(),
|
||||||
|
m_oLine.getAD_Client_ID(), m_oLine.getAD_Org_ID());
|
||||||
|
if (rate == null)
|
||||||
|
{
|
||||||
|
return "Purchase Order not convertible - " + as.getName();
|
||||||
|
}
|
||||||
|
poCost = poCost.multiply(rate);
|
||||||
|
if (poCost.scale() > as.getCostingPrecision())
|
||||||
|
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
||||||
|
tAmt = tAmt.multiply(rate);
|
||||||
|
if (tAmt.scale() > as.getCostingPrecision())
|
||||||
|
tAmt = tAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Total Amount and Total Quantity from Matched PO
|
||||||
|
if (!MCostDetail.createOrder(as, m_oLine.getAD_Org_ID(),
|
||||||
|
getM_Product_ID(), mMatchPO.getM_AttributeSetInstance_ID(),
|
||||||
|
m_oLine.getC_OrderLine_ID(), 0, // no cost element
|
||||||
|
tAmt, tQty, // Delivered
|
||||||
|
m_oLine.getDescription(), getTrxName()))
|
||||||
|
{
|
||||||
|
return "SaveError";
|
||||||
|
}
|
||||||
|
// end MZ
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
} // Doc_MatchPO
|
} // Doc_MatchPO
|
||||||
|
|
|
@ -131,10 +131,19 @@ public class Doc_Movement extends Doc
|
||||||
for (int i = 0; i < p_lines.length; i++)
|
for (int i = 0; i < p_lines.length; i++)
|
||||||
{
|
{
|
||||||
DocLine line = p_lines[i];
|
DocLine line = p_lines[i];
|
||||||
// MZ Goodwill
|
BigDecimal costs = null;
|
||||||
// if Inventory Move CostDetail exist then get Cost from Cost Detail
|
|
||||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'");
|
if (!isReversal(line))
|
||||||
// end MZ
|
{
|
||||||
|
// MZ Goodwill
|
||||||
|
// if Inventory Move CostDetail exist then get Cost from Cost Detail
|
||||||
|
costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'");
|
||||||
|
// end MZ
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
costs = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
// ** Inventory DR CR
|
// ** Inventory DR CR
|
||||||
dr = fact.createLine(line,
|
dr = fact.createLine(line,
|
||||||
|
@ -144,7 +153,7 @@ public class Doc_Movement extends Doc
|
||||||
continue;
|
continue;
|
||||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||||
dr.setQty(line.getQty().negate()); // outgoing
|
dr.setQty(line.getQty().negate()); // outgoing
|
||||||
if (m_DocStatus.equals(MMovement.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctDr from Original Movement
|
// Set AmtAcctDr from Original Movement
|
||||||
if (!dr.updateReverseLine (MMovement.Table_ID,
|
if (!dr.updateReverseLine (MMovement.Table_ID,
|
||||||
|
@ -163,7 +172,7 @@ public class Doc_Movement extends Doc
|
||||||
continue;
|
continue;
|
||||||
cr.setM_Locator_ID(line.getM_LocatorTo_ID());
|
cr.setM_Locator_ID(line.getM_LocatorTo_ID());
|
||||||
cr.setQty(line.getQty());
|
cr.setQty(line.getQty());
|
||||||
if (m_DocStatus.equals(MMovement.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0)
|
if (isReversal(line))
|
||||||
{
|
{
|
||||||
// Set AmtAcctCr from Original Movement
|
// Set AmtAcctCr from Original Movement
|
||||||
if (!cr.updateReverseLine (MMovement.Table_ID,
|
if (!cr.updateReverseLine (MMovement.Table_ID,
|
||||||
|
@ -186,17 +195,25 @@ public class Doc_Movement extends Doc
|
||||||
if (description == null)
|
if (description == null)
|
||||||
description = "";
|
description = "";
|
||||||
// Cost Detail From
|
// Cost Detail From
|
||||||
MCostDetail.createMovement(as, dr.getAD_Org_ID(), // locator org
|
if (!MCostDetail.createMovement(as, dr.getAD_Org_ID(), // locator org
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs.negate(), line.getQty().negate(), true,
|
costs.negate(), line.getQty().negate(), true,
|
||||||
description + "(|->)", getTrxName());
|
description + "(|->)", getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// Cost Detail To
|
// Cost Detail To
|
||||||
MCostDetail.createMovement(as, cr.getAD_Org_ID(), // locator org
|
if (!MCostDetail.createMovement(as, cr.getAD_Org_ID(), // locator org
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs, line.getQty(), false,
|
costs, line.getQty(), false,
|
||||||
description + "(|<-)", getTrxName());
|
description + "(|<-)", getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,4 +223,8 @@ public class Doc_Movement extends Doc
|
||||||
return facts;
|
return facts;
|
||||||
} // createFact
|
} // createFact
|
||||||
|
|
||||||
|
private boolean isReversal(DocLine line) {
|
||||||
|
return m_DocStatus.equals(MMovement.DOCSTATUS_Reversed) && m_Reversal_ID !=0 && line.getReversalLine_ID() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // Doc_Movement
|
} // Doc_Movement
|
||||||
|
|
|
@ -228,11 +228,15 @@ public class Doc_Production extends Doc
|
||||||
description = "";
|
description = "";
|
||||||
if (line.isProductionBOM())
|
if (line.isProductionBOM())
|
||||||
description += "(*)";
|
description += "(*)";
|
||||||
MCostDetail.createProduction(as, line.getAD_Org_ID(),
|
if (!MCostDetail.createProduction(as, line.getAD_Org_ID(),
|
||||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
line.get_ID(), 0,
|
line.get_ID(), 0,
|
||||||
costs, line.getQty(),
|
costs, line.getQty(),
|
||||||
description, getTrxName());
|
description, getTrxName()))
|
||||||
|
{
|
||||||
|
p_Error = "Failed to create cost detail record";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||||
|
|
|
@ -473,14 +473,6 @@ public class MInventory extends X_M_Inventory implements DocAction
|
||||||
m_processMsg = "Transaction not inserted(2)";
|
m_processMsg = "Transaction not inserted(2)";
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
if(QtyMA.signum() != 0)
|
|
||||||
{
|
|
||||||
String err = createCostDetail(line, ma.getM_AttributeSetInstance_ID() , QtyMA.negate());
|
|
||||||
if (err != null && err.length() > 0) {
|
|
||||||
m_processMsg = err;
|
|
||||||
return DocAction.STATUS_Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qtyDiff = QtyNew;
|
qtyDiff = QtyNew;
|
||||||
|
|
||||||
|
@ -530,16 +522,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
||||||
{
|
{
|
||||||
m_processMsg = "Transaction not inserted(2)";
|
m_processMsg = "Transaction not inserted(2)";
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(qtyDiff.signum() != 0)
|
|
||||||
{
|
|
||||||
String err = createCostDetail(line, line.getM_AttributeSetInstance_ID(), qtyDiff);
|
|
||||||
if (err != null && err.length() > 0) {
|
|
||||||
m_processMsg = err;
|
|
||||||
return DocAction.STATUS_Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // Fallback
|
} // Fallback
|
||||||
} // stock movement
|
} // stock movement
|
||||||
|
|
||||||
|
@ -941,60 +924,6 @@ public class MInventory extends X_M_Inventory implements DocAction
|
||||||
return m_reversal;
|
return m_reversal;
|
||||||
} // isReversal
|
} // isReversal
|
||||||
|
|
||||||
/**
|
|
||||||
* Create Cost Detail
|
|
||||||
* @param line
|
|
||||||
* @param Qty
|
|
||||||
* @return an EMPTY String on success otherwise an ERROR message
|
|
||||||
*/
|
|
||||||
private String createCostDetail(MInventoryLine line, int M_AttributeSetInstance_ID, BigDecimal qty)
|
|
||||||
{
|
|
||||||
// Get Account Schemas to create MCostDetail
|
|
||||||
MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID());
|
|
||||||
for(int asn = 0; asn < acctschemas.length; asn++)
|
|
||||||
{
|
|
||||||
MAcctSchema as = acctschemas[asn];
|
|
||||||
|
|
||||||
if (as.isSkipOrg(getAD_Org_ID()) || as.isSkipOrg(line.getAD_Org_ID()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal costs = Env.ZERO;
|
|
||||||
if (isReversal())
|
|
||||||
{
|
|
||||||
String sql = "SELECT amt * -1 FROM M_CostDetail WHERE M_InventoryLine_ID=?"; // negate costs
|
|
||||||
MProduct product = new MProduct(getCtx(), line.getM_Product_ID(), line.get_TrxName());
|
|
||||||
String CostingLevel = product.getCostingLevel(as);
|
|
||||||
if (MAcctSchema.COSTINGLEVEL_Organization.equals(CostingLevel))
|
|
||||||
sql = sql + " AND AD_Org_ID=" + getAD_Org_ID();
|
|
||||||
else if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel) && M_AttributeSetInstance_ID != 0)
|
|
||||||
sql = sql + " AND M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID;
|
|
||||||
costs = DB.getSQLValueBD(line.get_TrxName(), sql, line.getReversalLine_ID());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProductCost pc = new ProductCost (getCtx(),
|
|
||||||
line.getM_Product_ID(), M_AttributeSetInstance_ID, line.get_TrxName());
|
|
||||||
pc.setQty(qty);
|
|
||||||
costs = pc.getProductCosts(as, line.getAD_Org_ID(), as.getCostingMethod(), 0,true);
|
|
||||||
}
|
|
||||||
if (costs == null)
|
|
||||||
{
|
|
||||||
return "No Costs for " + line.getProduct().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Total Amount and Total Quantity from Inventory
|
|
||||||
MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
|
||||||
line.getM_Product_ID(), M_AttributeSetInstance_ID,
|
|
||||||
line.getM_InventoryLine_ID(), 0, // no cost element
|
|
||||||
costs, qty,
|
|
||||||
line.getDescription(), line.get_TrxName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Document Status is Complete or Closed
|
* Document Status is Complete or Closed
|
||||||
* @return true if CO, CL or RE
|
* @return true if CO, CL or RE
|
||||||
|
|
|
@ -136,6 +136,7 @@ public class MMatchInv extends X_M_MatchInv
|
||||||
|
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static CLogger s_log = CLogger.getCLogger (MMatchInv.class);
|
private static CLogger s_log = CLogger.getCLogger (MMatchInv.class);
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,29 +222,6 @@ public class MMatchInv extends X_M_MatchInv
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
/**
|
|
||||||
* After Save.
|
|
||||||
* Set Order Qty Delivered/Invoiced
|
|
||||||
* @param newRecord new
|
|
||||||
* @param success success
|
|
||||||
* @return success
|
|
||||||
*/
|
|
||||||
protected boolean afterSave (boolean newRecord, boolean success)
|
|
||||||
{
|
|
||||||
if (newRecord && success)
|
|
||||||
{
|
|
||||||
// Elaine 2008/6/20
|
|
||||||
String err = createMatchInvCostDetail();
|
|
||||||
if(err != null && err.length() > 0)
|
|
||||||
{
|
|
||||||
s_log.warning(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return success;
|
|
||||||
} // afterSave
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the later Date Acct from invoice or shipment
|
* Get the later Date Acct from invoice or shipment
|
||||||
* @return date or null
|
* @return date or null
|
||||||
|
@ -329,81 +307,6 @@ public class MMatchInv extends X_M_MatchInv
|
||||||
return success;
|
return success;
|
||||||
} // afterDelete
|
} // afterDelete
|
||||||
|
|
||||||
|
|
||||||
// Elaine 2008/6/20
|
|
||||||
private String createMatchInvCostDetail()
|
|
||||||
{
|
|
||||||
MInvoiceLine invoiceLine = new MInvoiceLine (getCtx(), getC_InvoiceLine_ID(), get_TrxName());
|
|
||||||
|
|
||||||
// Get Account Schemas to create MCostDetail
|
|
||||||
MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID());
|
|
||||||
for(int asn = 0; asn < acctschemas.length; asn++)
|
|
||||||
{
|
|
||||||
MAcctSchema as = acctschemas[asn];
|
|
||||||
|
|
||||||
if (as.isSkipOrg(getAD_Org_ID()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal LineNetAmt = invoiceLine.getLineNetAmt();
|
|
||||||
BigDecimal multiplier = getQty()
|
|
||||||
.divide(invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP)
|
|
||||||
.abs();
|
|
||||||
if (multiplier.compareTo(Env.ONE) != 0)
|
|
||||||
LineNetAmt = LineNetAmt.multiply(multiplier);
|
|
||||||
|
|
||||||
// Source from Doc_MatchInv.createFacts(MAcctSchema)
|
|
||||||
// Cost Detail Record - data from Expense/IncClearing (CR) record
|
|
||||||
// MZ Goodwill
|
|
||||||
// Create Cost Detail Matched Invoice using Total Amount and Total Qty based on InvoiceLine
|
|
||||||
MMatchInv[] mInv = MMatchInv.getInvoiceLine(getCtx(), invoiceLine.getC_InvoiceLine_ID(), get_TrxName());
|
|
||||||
BigDecimal tQty = Env.ZERO;
|
|
||||||
BigDecimal tAmt = Env.ZERO;
|
|
||||||
for (int i = 0 ; i < mInv.length ; i++)
|
|
||||||
{
|
|
||||||
if (mInv[i].isPosted() && mInv[i].getM_MatchInv_ID() != get_ID())
|
|
||||||
{
|
|
||||||
tQty = tQty.add(mInv[i].getQty());
|
|
||||||
multiplier = mInv[i].getQty()
|
|
||||||
.divide(invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP).abs();
|
|
||||||
tAmt = tAmt.add(invoiceLine.getLineNetAmt().multiply(multiplier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tAmt = tAmt.add(LineNetAmt); //Invoice Price
|
|
||||||
|
|
||||||
// Different currency
|
|
||||||
MInvoice invoice = invoiceLine.getParent();
|
|
||||||
if (as.getC_Currency_ID() != invoice.getC_Currency_ID())
|
|
||||||
{
|
|
||||||
tAmt = MConversionRate.convert(getCtx(), tAmt,
|
|
||||||
invoice.getC_Currency_ID(), as.getC_Currency_ID(),
|
|
||||||
invoice.getDateAcct(), invoice.getC_ConversionType_ID(),
|
|
||||||
invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
|
|
||||||
if (tAmt == null)
|
|
||||||
{
|
|
||||||
return "AP Invoice not convertible - " + as.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set Qty to negative value when MovementType is Vendor Returns
|
|
||||||
MInOutLine receiptLine = new MInOutLine (getCtx(),getM_InOutLine_ID(), get_TrxName());
|
|
||||||
MInOut receipt = receiptLine.getParent();
|
|
||||||
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
|
|
||||||
tQty = tQty.add(getQty().negate()); // Qty is set to negative value
|
|
||||||
else
|
|
||||||
tQty = tQty.add(getQty());
|
|
||||||
|
|
||||||
// Set Total Amount and Total Quantity from Matched Invoice
|
|
||||||
MCostDetail.createInvoice(as, getAD_Org_ID(),
|
|
||||||
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
|
||||||
invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
|
|
||||||
tAmt, tQty, getDescription(), get_TrxName());
|
|
||||||
// end MZ
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
//AZ Goodwill
|
//AZ Goodwill
|
||||||
private String deleteMatchInvCostDetail()
|
private String deleteMatchInvCostDetail()
|
||||||
|
@ -424,29 +327,36 @@ public class MMatchInv extends X_M_MatchInv
|
||||||
getC_InvoiceLine_ID(), getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), get_TrxName());
|
getC_InvoiceLine_ID(), getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), get_TrxName());
|
||||||
if (cd != null)
|
if (cd != null)
|
||||||
{
|
{
|
||||||
MInOut receipt = (new MInOutLine(getCtx(),getM_InOutLine_ID(),get_TrxName())).getParent();
|
if (cd.isProcessed())
|
||||||
BigDecimal qty = getQty();
|
|
||||||
if (receipt.getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns))
|
|
||||||
qty = getQty().negate();
|
|
||||||
//
|
|
||||||
BigDecimal price = null;
|
|
||||||
if (cd.getQty().compareTo(Env.ZERO) == 0) // avoid division by zero
|
|
||||||
price = Env.ZERO;
|
|
||||||
else
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
cd.process();
|
|
||||||
}
|
|
||||||
if (cd.getQty().compareTo(Env.ZERO) == 0)
|
|
||||||
{
|
{
|
||||||
|
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 = null;
|
||||||
|
if (cd.getQty().compareTo(Env.ZERO) == 0) // avoid division by zero
|
||||||
|
price = Env.ZERO;
|
||||||
|
else
|
||||||
|
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.setProcessed(false);
|
||||||
|
//
|
||||||
|
cd.setAmt(price.multiply(cd.getQty().subtract(qty)));
|
||||||
|
cd.setQty(cd.getQty().subtract(qty));
|
||||||
|
if (!cd.isProcessed())
|
||||||
|
{
|
||||||
|
cd.process();
|
||||||
|
}
|
||||||
|
if (cd.getQty().compareTo(Env.ZERO) == 0)
|
||||||
|
{
|
||||||
|
cd.setProcessed(false);
|
||||||
|
cd.delete(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
cd.delete(true);
|
cd.delete(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,17 +619,6 @@ public class MMatchPO extends X_M_MatchPO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newRecord || m_isInOutLineChange)
|
|
||||||
{
|
|
||||||
// Elaine 2008/6/20
|
|
||||||
String err = createMatchPOCostDetail();
|
|
||||||
if(err != null && err.length() > 0)
|
|
||||||
{
|
|
||||||
s_log.warning(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
@ -853,113 +842,6 @@ public class MMatchPO extends X_M_MatchPO
|
||||||
s_log.info("Success #" + success + " - Error #" + errors);
|
s_log.info("Success #" + success + " - Error #" + errors);
|
||||||
} // consolidate
|
} // consolidate
|
||||||
|
|
||||||
// Elaine 2008/6/20
|
|
||||||
private String createMatchPOCostDetail()
|
|
||||||
{
|
|
||||||
if (getM_InOutLine_ID() != 0)
|
|
||||||
{
|
|
||||||
MOrderLine oLine = getOrderLine();
|
|
||||||
|
|
||||||
// Get Account Schemas to create MCostDetail
|
|
||||||
MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID());
|
|
||||||
for(int asn = 0; asn < acctschemas.length; asn++)
|
|
||||||
{
|
|
||||||
MAcctSchema as = acctschemas[asn];
|
|
||||||
|
|
||||||
if (as.isSkipOrg(getAD_Org_ID()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Purchase Order Line
|
|
||||||
BigDecimal poCost = oLine.getPriceCost();
|
|
||||||
if (poCost == null || poCost.signum() == 0)
|
|
||||||
{
|
|
||||||
poCost = oLine.getPriceActual();
|
|
||||||
// Goodwill: Correct included Tax
|
|
||||||
int C_Tax_ID = oLine.getC_Tax_ID();
|
|
||||||
if (oLine.isTaxIncluded() && C_Tax_ID != 0)
|
|
||||||
{
|
|
||||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
|
||||||
if (!tax.isZeroTax())
|
|
||||||
{
|
|
||||||
int stdPrecision = MCurrency.getStdPrecision(getCtx(), oLine.getC_Currency_ID());
|
|
||||||
BigDecimal costTax = tax.calculateTax(poCost, true, stdPrecision);
|
|
||||||
log.fine("Costs=" + poCost + " - Tax=" + costTax);
|
|
||||||
poCost = poCost.subtract(costTax);
|
|
||||||
}
|
|
||||||
} // correct included Tax
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source from Doc_MatchPO.createFacts(MAcctSchema)
|
|
||||||
MInOutLine receiptLine = new MInOutLine (getCtx(), getM_InOutLine_ID(), get_TrxName());
|
|
||||||
MInOut inOut = receiptLine.getParent();
|
|
||||||
boolean isReturnTrx = inOut.getMovementType().equals(X_M_InOut.MOVEMENTTYPE_VendorReturns);
|
|
||||||
|
|
||||||
// Create PO Cost Detail Record first
|
|
||||||
// MZ Goodwill
|
|
||||||
// Create Cost Detail Matched PO using Total Amount and Total Qty based on OrderLine
|
|
||||||
MMatchPO[] mPO = MMatchPO.getOrderLine(getCtx(), oLine.getC_OrderLine_ID(), get_TrxName());
|
|
||||||
BigDecimal tQty = Env.ZERO;
|
|
||||||
BigDecimal tAmt = Env.ZERO;
|
|
||||||
for (int i = 0 ; i < mPO.length ; i++)
|
|
||||||
{
|
|
||||||
if (mPO[i].getM_AttributeSetInstance_ID() == getM_AttributeSetInstance_ID()
|
|
||||||
&& mPO[i].getM_MatchPO_ID() != get_ID())
|
|
||||||
{
|
|
||||||
BigDecimal qty = (isReturnTrx ? mPO[i].getQty().negate() : mPO[i].getQty());
|
|
||||||
tQty = tQty.add(qty);
|
|
||||||
tAmt = tAmt.add(poCost.multiply(qty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
poCost = poCost.multiply(getQty()); // Delivered so far
|
|
||||||
tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost);
|
|
||||||
tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty());
|
|
||||||
|
|
||||||
// Different currency
|
|
||||||
if (oLine.getC_Currency_ID() != as.getC_Currency_ID())
|
|
||||||
{
|
|
||||||
MOrder order = oLine.getParent();
|
|
||||||
Timestamp dateAcct = order.getDateAcct();
|
|
||||||
//get costing method for product
|
|
||||||
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
|
||||||
String costingMethod = product.getCostingMethod(as);
|
|
||||||
if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) ||
|
|
||||||
MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) )
|
|
||||||
dateAcct = inOut.getDateAcct(); //Movement Date
|
|
||||||
//
|
|
||||||
BigDecimal rate = MConversionRate.getRate(
|
|
||||||
order.getC_Currency_ID(), as.getC_Currency_ID(),
|
|
||||||
dateAcct, order.getC_ConversionType_ID(),
|
|
||||||
oLine.getAD_Client_ID(), oLine.getAD_Org_ID());
|
|
||||||
if (rate == null)
|
|
||||||
{
|
|
||||||
return "Purchase Order not convertible - " + as.getName();
|
|
||||||
}
|
|
||||||
poCost = poCost.multiply(rate);
|
|
||||||
if (poCost.scale() > as.getCostingPrecision())
|
|
||||||
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
|
||||||
tAmt = tAmt.multiply(rate);
|
|
||||||
if (tAmt.scale() > as.getCostingPrecision())
|
|
||||||
tAmt = tAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Total Amount and Total Quantity from Matched PO
|
|
||||||
if (!MCostDetail.createOrder(as, oLine.getAD_Org_ID(),
|
|
||||||
getM_Product_ID(), getM_AttributeSetInstance_ID(),
|
|
||||||
oLine.getC_OrderLine_ID(), 0, // no cost element
|
|
||||||
tAmt, tQty, // Delivered
|
|
||||||
oLine.getDescription(), get_TrxName()))
|
|
||||||
{
|
|
||||||
return "SaveError";
|
|
||||||
}
|
|
||||||
// end MZ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//AZ Goodwill
|
//AZ Goodwill
|
||||||
private String deleteMatchPOCostDetail()
|
private String deleteMatchPOCostDetail()
|
||||||
{
|
{
|
||||||
|
@ -979,24 +861,31 @@ public class MMatchPO extends X_M_MatchPO
|
||||||
getC_OrderLine_ID(), getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), get_TrxName());
|
getC_OrderLine_ID(), getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), get_TrxName());
|
||||||
if (cd != null)
|
if (cd != null)
|
||||||
{
|
{
|
||||||
if (cd.getQty().compareTo(Env.ZERO) > 0)
|
if (cd.isProcessed())
|
||||||
{
|
{
|
||||||
BigDecimal price = cd.getAmt().divide(cd.getQty(),12,BigDecimal.ROUND_HALF_UP);
|
if (cd.getQty().compareTo(Env.ZERO) > 0)
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
cd.process();
|
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())
|
||||||
|
{
|
||||||
|
cd.process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//after process clean-up
|
||||||
|
if (cd.getQty().compareTo(Env.ZERO) == 0)
|
||||||
|
{
|
||||||
|
cd.setProcessed(false);
|
||||||
|
cd.delete(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//after process clean-up
|
else
|
||||||
if (cd.getQty().compareTo(Env.ZERO) == 0)
|
|
||||||
{
|
{
|
||||||
cd.setProcessed(false);
|
|
||||||
cd.delete(true);
|
cd.delete(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue