IDEMPIERE-1180 Cost Adjustment Document for Standard and Average Costing.
This commit is contained in:
parent
0cead2d7f9
commit
db5e974ab7
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,6 +20,11 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
|
|
|
@ -6,4 +6,6 @@ Bundle-Version: 1.0.0.qualifier
|
|||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: org.adempiere.base;bundle-version="1.0.0"
|
||||
Eclipse-RegisterBuddy: org.adempiere.base
|
||||
Service-Component: OSGI-INF/costadjustmentcalloutfactory.xml
|
||||
Bundle-ActivationPolicy: lazy
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.callout.CostAdjustmentCalloutFactory">
|
||||
<implementation class="org.adempiere.base.callout.CostAdjustmentCalloutFactory"/>
|
||||
<service>
|
||||
<provide interface="org.adempiere.base.IColumnCalloutFactory"/>
|
||||
</service>
|
||||
</scr:component>
|
|
@ -1,4 +1,6 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
.,\
|
||||
OSGI-INF/costadjustmentcalloutfactory.xml,\
|
||||
OSGI-INF/
|
||||
source.. = src/
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.adempiere.base.callout;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.adempiere.base.IColumnCallout;
|
||||
import org.adempiere.base.IColumnCalloutFactory;
|
||||
import org.compiere.model.GridField;
|
||||
import org.compiere.model.GridTab;
|
||||
import org.compiere.model.I_M_InventoryLine;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCostElement;
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class CostAdjustmentCalloutFactory implements IColumnCalloutFactory {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public CostAdjustmentCalloutFactory() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.adempiere.base.IColumnCalloutFactory#getColumnCallouts(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public IColumnCallout[] getColumnCallouts(String tableName,
|
||||
String columnName) {
|
||||
if (tableName.equalsIgnoreCase(I_M_InventoryLine.Table_Name)) {
|
||||
if (columnName.equalsIgnoreCase(I_M_InventoryLine.COLUMNNAME_M_Product_ID))
|
||||
return new IColumnCallout[]{new CostAdjustmentLineProduct()};
|
||||
else if (columnName.equalsIgnoreCase(I_M_InventoryLine.COLUMNNAME_M_AttributeSetInstance_ID))
|
||||
return new IColumnCallout[]{new CostAdjustmentLineASI()};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* callout for m_product_id
|
||||
*/
|
||||
private static class CostAdjustmentLineProduct implements IColumnCallout {
|
||||
@Override
|
||||
public String start(Properties ctx, int WindowNo, GridTab mTab,
|
||||
GridField mField, Object value, Object oldValue) {
|
||||
MInventory inventory = MInventory.get(ctx, (Integer) mTab.getValue("M_Inventory_ID"));
|
||||
if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(inventory.getC_DocType().getDocSubTypeInv())) {
|
||||
String costingMethod = inventory.getCostingMethod();
|
||||
if (value == null) {
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_CurrentCostPrice, BigDecimal.ZERO);
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_NewCostPrice, BigDecimal.ZERO);
|
||||
} else {
|
||||
MProduct product = MProduct.get(ctx, (Integer) value);
|
||||
MClient client = MClient.get(ctx);
|
||||
MAcctSchema as = client.getAcctSchema();
|
||||
Object asiValue = mTab.getValue(I_M_InventoryLine.COLUMNNAME_M_AttributeSetInstance_ID);
|
||||
int M_ASI_ID = asiValue != null ? (Integer)asiValue : 0;
|
||||
int AD_Org_ID = inventory.getAD_Org_ID();
|
||||
MCost cost = product.getCostingRecord(as, AD_Org_ID, M_ASI_ID, costingMethod);
|
||||
if (cost == null) {
|
||||
if (!MCostElement.COSTINGMETHOD_StandardCosting.equals(costingMethod)) {
|
||||
mTab.setValue(mField, null);
|
||||
return Msg.getMsg(Env.getCtx(), "NoCostingRecord");
|
||||
}
|
||||
}
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_CurrentCostPrice, cost.getCurrentCostPrice());
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_NewCostPrice, cost.getCurrentCostPrice());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* callout for m_attributesetinstance_id
|
||||
*/
|
||||
private class CostAdjustmentLineASI implements IColumnCallout {
|
||||
@Override
|
||||
public String start(Properties ctx, int WindowNo, GridTab mTab,
|
||||
GridField mField, Object value, Object oldValue) {
|
||||
MInventory inventory = MInventory.get(ctx, (Integer) mTab.getValue("M_Inventory_ID"));
|
||||
if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(inventory.getC_DocType().getDocSubTypeInv())) {
|
||||
String costingMethod = inventory.getCostingMethod();
|
||||
Object productValue = mTab.getValue(I_M_InventoryLine.COLUMNNAME_M_Product_ID);
|
||||
if (productValue == null || ((Integer)productValue).intValue() == 0) return null;
|
||||
|
||||
MProduct product = MProduct.get(ctx, (Integer)productValue);
|
||||
int M_ASI_ID = value != null ? (Integer)value : 0;
|
||||
int AD_Org_ID = inventory.getAD_Org_ID();
|
||||
MClient client = MClient.get(ctx);
|
||||
MAcctSchema as = client.getAcctSchema();
|
||||
MCost cost = product.getCostingRecord(as, AD_Org_ID, M_ASI_ID, costingMethod);
|
||||
if (cost != null) {
|
||||
BigDecimal currentCost = (BigDecimal) mTab.getValue(I_M_InventoryLine.COLUMNNAME_CurrentCostPrice);
|
||||
if (currentCost == null || currentCost.compareTo(cost.getCurrentCostPrice())==0) return null;
|
||||
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_CurrentCostPrice, cost.getCurrentCostPrice());
|
||||
mTab.setValue(I_M_InventoryLine.COLUMNNAME_NewCostPrice, cost.getCurrentCostPrice());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,17 +19,27 @@ package org.compiere.process;
|
|||
import java.math.BigDecimal;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.model.I_C_DocType;
|
||||
import org.compiere.model.I_M_Inventory;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCostElement;
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.util.AdempiereSystemError;
|
||||
import org.compiere.util.AdempiereUserError;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
|
||||
/**
|
||||
* Standard Cost Update
|
||||
|
@ -48,6 +58,8 @@ public class CostUpdate extends SvrProcess
|
|||
/** PLV */
|
||||
private int p_M_PriceList_Version_ID = 0;
|
||||
|
||||
private int p_C_DocType_ID = 0;
|
||||
|
||||
|
||||
private static final String TO_AveragePO = "A";
|
||||
private static final String TO_AverageInvoiceHistory = "DI";
|
||||
|
@ -67,6 +79,7 @@ public class CostUpdate extends SvrProcess
|
|||
private MAcctSchema[] m_ass = null;
|
||||
/** Map of Cost Elements */
|
||||
private HashMap<String,MCostElement> m_ces = new HashMap<String,MCostElement>();
|
||||
private MDocType m_docType = null;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -89,6 +102,8 @@ public class CostUpdate extends SvrProcess
|
|||
p_SetStandardCostTo = (String)para[i].getParameter();
|
||||
else if (name.equals("M_PriceList_Version_ID"))
|
||||
p_M_PriceList_Version_ID = para[i].getParameterAsInt();
|
||||
else if (name.equals("C_DocType_ID"))
|
||||
p_C_DocType_ID = para[i].getParameterAsInt();
|
||||
else
|
||||
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||
}
|
||||
|
@ -114,6 +129,13 @@ public class CostUpdate extends SvrProcess
|
|||
{
|
||||
return "-";
|
||||
}
|
||||
if (!Util.isEmpty(p_SetStandardCostTo))
|
||||
{
|
||||
if (p_C_DocType_ID <= 0)
|
||||
throw new AdempiereUserError ("@FillMandatory@ @C_DocType_ID@");
|
||||
else
|
||||
m_docType = MDocType.get(getCtx(), p_C_DocType_ID);
|
||||
}
|
||||
// PLV required
|
||||
if (p_M_PriceList_Version_ID == 0
|
||||
&& (p_SetFutureCostTo.equals(TO_PriceListLimit) || p_SetStandardCostTo.equals(TO_PriceListLimit)))
|
||||
|
@ -253,13 +275,17 @@ public class CostUpdate extends SvrProcess
|
|||
ResultSet rs = null;
|
||||
try
|
||||
{
|
||||
List<MInventoryLine> lines = new ArrayList<MInventoryLine>();
|
||||
MClient client = MClient.get(getCtx());
|
||||
MAcctSchema primarySchema = client.getAcctSchema();
|
||||
MInventory inventoryDoc = null;
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, m_ce.getM_CostElement_ID());
|
||||
if (p_M_Product_Category_ID != 0)
|
||||
pstmt.setInt (2, p_M_Product_Category_ID);
|
||||
rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
{
|
||||
MCost cost = new MCost (getCtx(), rs, get_TrxName());
|
||||
for (int i = 0; i < m_ass.length; i++)
|
||||
{
|
||||
|
@ -267,15 +293,65 @@ public class CostUpdate extends SvrProcess
|
|||
if (m_ass[i].getC_AcctSchema_ID() == cost.getC_AcctSchema_ID()
|
||||
&& m_ass[i].getM_CostType_ID() == cost.getM_CostType_ID())
|
||||
{
|
||||
if (update (cost))
|
||||
counter++;
|
||||
if (m_ass[i].getC_AcctSchema_ID() == primarySchema.getC_AcctSchema_ID())
|
||||
{
|
||||
if (update (cost, lines))
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update (cost, null))
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lines.size() > 0)
|
||||
{
|
||||
inventoryDoc = new MInventory(getCtx(), 0, get_TrxName());
|
||||
inventoryDoc.setC_DocType_ID(p_C_DocType_ID);
|
||||
inventoryDoc.setCostingMethod(MCostElement.COSTINGMETHOD_StandardCosting);
|
||||
inventoryDoc.setDocAction(DocAction.ACTION_Complete);
|
||||
inventoryDoc.saveEx();
|
||||
|
||||
for(MInventoryLine line : lines)
|
||||
{
|
||||
line.setM_Inventory_ID(inventoryDoc.getM_Inventory_ID());
|
||||
line.saveEx();
|
||||
}
|
||||
|
||||
if (!DocumentEngine.processIt(inventoryDoc, DocAction.ACTION_Complete))
|
||||
{
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append(Msg.getMsg(getCtx(), "ProcessFailed")).append(": ");
|
||||
if (Env.isBaseLanguage(getCtx(), I_C_DocType.Table_Name))
|
||||
msg.append(m_docType.getName());
|
||||
else
|
||||
msg.append(m_docType.get_Translation(I_C_DocType.COLUMNNAME_Name));
|
||||
throw new AdempiereUserError(msg.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryDoc.saveEx();
|
||||
StringBuilder msg = new StringBuilder();
|
||||
if (Env.isBaseLanguage(getCtx(), I_C_DocType.Table_Name))
|
||||
msg.append(m_docType.getName()).append(" ").append(inventoryDoc.getDocumentNo());
|
||||
else
|
||||
msg.append(m_docType.get_Translation(I_C_DocType.COLUMNNAME_Name)).append(" ").append(inventoryDoc.getDocumentNo());
|
||||
addLog(getAD_PInstance_ID(), null, null, msg.toString(), I_M_Inventory.Table_ID, inventoryDoc.getM_Inventory_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log (Level.SEVERE, sql, e);
|
||||
if (e instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)e;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -291,10 +367,11 @@ public class CostUpdate extends SvrProcess
|
|||
/**
|
||||
* Update Cost Records
|
||||
* @param cost cost
|
||||
* @param inventoryDoc
|
||||
* @return true if updated
|
||||
* @throws Exception
|
||||
*/
|
||||
private boolean update (MCost cost) throws Exception
|
||||
private boolean update (MCost cost, List<MInventoryLine> lines) throws Exception
|
||||
{
|
||||
boolean updated = false;
|
||||
if (p_SetFutureCostTo.equals(p_SetStandardCostTo))
|
||||
|
@ -302,21 +379,37 @@ public class CostUpdate extends SvrProcess
|
|||
BigDecimal costs = getCosts(cost, p_SetFutureCostTo);
|
||||
if (costs != null && costs.signum() != 0)
|
||||
{
|
||||
cost.setFutureCostPrice(costs);
|
||||
cost.setCurrentCostPrice(costs);
|
||||
cost.setFutureCostPrice(costs);
|
||||
updated = true;
|
||||
}
|
||||
if (lines != null)
|
||||
{
|
||||
MInventoryLine line = new MInventoryLine(getCtx(), 0, get_TrxName());
|
||||
line.setM_Product_ID(cost.getM_Product_ID());
|
||||
line.setCurrentCostPrice(cost.getCurrentCostPrice());
|
||||
line.setNewCostPrice(costs);
|
||||
line.setM_Locator_ID(0);
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_SetStandardCostTo.length() > 0)
|
||||
{
|
||||
BigDecimal costs = getCosts(cost, p_SetStandardCostTo);
|
||||
if (costs != null && costs.signum() != 0)
|
||||
if (lines != null)
|
||||
{
|
||||
cost.setCurrentCostPrice(costs);
|
||||
updated = true;
|
||||
}
|
||||
BigDecimal costs = getCosts(cost, p_SetStandardCostTo);
|
||||
if (costs != null && costs.signum() != 0)
|
||||
{
|
||||
MInventoryLine line = new MInventoryLine(getCtx(), 0, get_TrxName());
|
||||
line.setM_Product_ID(cost.getM_Product_ID());
|
||||
line.setCurrentCostPrice(cost.getCurrentCostPrice());
|
||||
line.setNewCostPrice(costs);
|
||||
line.setM_Locator_ID(0);
|
||||
lines.add(line);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_SetFutureCostTo.length() > 0)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2013 Heng Sin Low *
|
||||
* Copyright (C) 2013 Trek Global *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
*****************************************************************************/
|
||||
package org.idempiere.process;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.process.SvrProcess;
|
||||
|
||||
/**
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class CostAdjustmentLineRefreshCost extends SvrProcess {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public CostAdjustmentLineRefreshCost() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.compiere.process.SvrProcess#prepare()
|
||||
*/
|
||||
@Override
|
||||
protected void prepare() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.compiere.process.SvrProcess#doIt()
|
||||
*/
|
||||
@Override
|
||||
protected String doIt() throws Exception {
|
||||
MInventoryLine line = new MInventoryLine(getCtx(), getRecord_ID(), null);
|
||||
MProduct product = line.getProduct();
|
||||
MClient client = MClient.get(getCtx(), line.getAD_Client_ID());
|
||||
MAcctSchema as = client.getAcctSchema();
|
||||
MCost cost = product.getCostingRecord(as, line.getAD_Org_ID(), line.getM_AttributeSetInstance_ID(), line.getM_Inventory().getCostingMethod());
|
||||
if (cost != null) {
|
||||
line.setCurrentCostPrice(cost.getCurrentCostPrice());
|
||||
line.setNewCostPrice(cost.getCurrentCostPrice());
|
||||
line.saveEx();
|
||||
} else {
|
||||
line.setCurrentCostPrice(BigDecimal.ZERO);
|
||||
line.setNewCostPrice(BigDecimal.ZERO);
|
||||
line.saveEx();
|
||||
}
|
||||
|
||||
return "@Ok@";
|
||||
}
|
||||
}
|
|
@ -23,11 +23,17 @@ import java.util.logging.Level;
|
|||
|
||||
import org.compiere.model.MAccount;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MConversionRate;
|
||||
import org.compiere.model.MCost;
|
||||
import org.compiere.model.MCostDetail;
|
||||
import org.compiere.model.MCostElement;
|
||||
import org.compiere.model.MDocType;
|
||||
import org.compiere.model.MInventory;
|
||||
import org.compiere.model.MInventoryLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.ProductCost;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
|
||||
|
@ -49,6 +55,7 @@ public class Doc_Inventory extends Doc
|
|||
private int m_Reversal_ID = 0;
|
||||
@SuppressWarnings("unused")
|
||||
private String m_DocStatus = "";
|
||||
private String parentDocSubTypeInv;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -66,13 +73,24 @@ public class Doc_Inventory extends Doc
|
|||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID (NO_CURRENCY);
|
||||
{
|
||||
MInventory inventory = (MInventory)getPO();
|
||||
setDateDoc (inventory.getMovementDate());
|
||||
setDateAcct(inventory.getMovementDate());
|
||||
m_Reversal_ID = inventory.getReversal_ID();//store original (voided/reversed) document
|
||||
m_DocStatus = inventory.getDocStatus();
|
||||
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||
parentDocSubTypeInv = dt.getDocSubTypeInv();
|
||||
if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(parentDocSubTypeInv))
|
||||
{
|
||||
MClient client = MClient.get(getCtx(), inventory.getAD_Client_ID());
|
||||
int C_Currency_ID = client.getAcctSchema().getC_Currency_ID();
|
||||
setC_Currency_ID(C_Currency_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
setC_Currency_ID (NO_CURRENCY);
|
||||
}
|
||||
// Contained Objects
|
||||
p_lines = loadLines(inventory);
|
||||
if (log.isLoggable(Level.FINE)) log.fine("Lines=" + p_lines.length);
|
||||
|
@ -85,9 +103,7 @@ public class Doc_Inventory extends Doc
|
|||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MInventory inventory)
|
||||
{
|
||||
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||
String parentDocSubTypeInv = dt.getDocSubTypeInv();
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MInventoryLine[] lines = inventory.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
|
@ -106,16 +122,23 @@ public class Doc_Inventory extends Doc
|
|||
}
|
||||
|
||||
BigDecimal qtyDiff = Env.ZERO;
|
||||
BigDecimal amtDiff = Env.ZERO;
|
||||
if (MDocType.DOCSUBTYPEINV_InternalUseInventory.equals(docSubTypeInv))
|
||||
qtyDiff = line.getQtyInternalUse().negate();
|
||||
else if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
|
||||
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
|
||||
else if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(docSubTypeInv))
|
||||
amtDiff = line.getNewCostPrice().subtract(line.getCurrentCostPrice());
|
||||
// nothing to post
|
||||
if (qtyDiff.signum() == 0)
|
||||
if (qtyDiff.signum() == 0 && amtDiff.signum() == 0)
|
||||
continue;
|
||||
//
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
docLine.setQty (qtyDiff, false); // -5 => -5
|
||||
if (amtDiff.signum() != 0)
|
||||
{
|
||||
docLine.setAmount(amtDiff);
|
||||
}
|
||||
docLine.setReversalLine_ID(line.getReversalLine_ID());
|
||||
if (log.isLoggable(Level.FINE)) log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
|
@ -158,87 +181,159 @@ public class Doc_Inventory extends Doc
|
|||
FactLine dr = null;
|
||||
FactLine cr = null;
|
||||
|
||||
MInventory inventory = (MInventory) getPO();
|
||||
boolean costAdjustment = MDocType.DOCSUBTYPEINV_CostAdjustment.equals(parentDocSubTypeInv);
|
||||
String docCostingMethod = inventory.getCostingMethod();
|
||||
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
|
||||
boolean doPosting = true;
|
||||
String costingLevel = null;
|
||||
MProduct product = null;
|
||||
if (costAdjustment)
|
||||
{
|
||||
product = line.getProduct();
|
||||
String productCostingMethod = product.getCostingMethod(as);
|
||||
costingLevel = product.getCostingLevel(as);
|
||||
if (!docCostingMethod.equals(productCostingMethod))
|
||||
{
|
||||
doPosting = false;
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal costs = null;
|
||||
if (!isReversal(line))
|
||||
BigDecimal adjustmentDiff = null;
|
||||
if (costAdjustment)
|
||||
{
|
||||
// MZ Goodwill
|
||||
// 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)
|
||||
costs = line.getAmtSource();
|
||||
int orgId = line.getAD_Org_ID();
|
||||
int asiId = line.getM_AttributeSetInstance_ID();
|
||||
if (MAcctSchema.COSTINGLEVEL_Client.equals(costingLevel))
|
||||
{
|
||||
p_Error = "No Costs for " + line.getProduct().getName();
|
||||
return null;
|
||||
orgId = 0;
|
||||
asiId = 0;
|
||||
}
|
||||
else if (MAcctSchema.COSTINGLEVEL_Organization.equals(costingLevel))
|
||||
asiId = 0;
|
||||
else if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(costingLevel))
|
||||
orgId = 0;
|
||||
MCostElement ce = MCostElement.getMaterialCostElement(getCtx(), docCostingMethod, orgId);
|
||||
MCost cost = MCost.get(product, asiId, as,
|
||||
orgId, ce.getM_CostElement_ID(), getTrxName());
|
||||
DB.getDatabase().forUpdate(cost, 120);
|
||||
BigDecimal currentQty = cost.getCurrentQty();
|
||||
adjustmentDiff = costs;
|
||||
costs = costs.multiply(currentQty);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isReversal(line))
|
||||
{
|
||||
// MZ Goodwill
|
||||
// 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
|
||||
{
|
||||
//updated below
|
||||
costs = Env.ONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
costs = BigDecimal.ZERO;
|
||||
}
|
||||
// Inventory DR CR
|
||||
dr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), costs);
|
||||
// may be zero difference - no line created.
|
||||
if (dr == null)
|
||||
continue;
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
if (isReversal(line))
|
||||
{
|
||||
// Set AmtAcctDr from Original Phys.Inventory
|
||||
if (!dr.updateReverseLine (MInventory.Table_ID,
|
||||
m_Reversal_ID, line.getReversalLine_ID(),Env.ONE))
|
||||
|
||||
if (doPosting)
|
||||
{
|
||||
int C_Currency_ID = getC_Currency_ID() > 0 ? getC_Currency_ID() : as.getC_Currency_ID();
|
||||
// Inventory DR CR
|
||||
dr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
C_Currency_ID, costs);
|
||||
// may be zero difference - no line created.
|
||||
if (dr != null)
|
||||
{
|
||||
p_Error = "Original Physical Inventory not posted yet";
|
||||
return null;
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
if (isReversal(line))
|
||||
{
|
||||
// Set AmtAcctDr from Original Phys.Inventory
|
||||
if (!dr.updateReverseLine (MInventory.Table_ID,
|
||||
m_Reversal_ID, line.getReversalLine_ID(),Env.ONE))
|
||||
{
|
||||
p_Error = "Original Physical Inventory not posted yet";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// InventoryDiff DR CR
|
||||
// or Charge
|
||||
MAccount invDiff = null;
|
||||
if (isReversal(line)
|
||||
&& line.getC_Charge_ID() != 0) {
|
||||
invDiff = line.getChargeAccount(as, costs);
|
||||
} else {
|
||||
invDiff = line.getChargeAccount(as, costs.negate());
|
||||
}
|
||||
|
||||
if (invDiff == null)
|
||||
{
|
||||
if (costAdjustment)
|
||||
{
|
||||
invDiff = line.getProductCost().getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as);
|
||||
}
|
||||
else
|
||||
{
|
||||
invDiff = getAccount(Doc.ACCTTYPE_InvDifferences, as);
|
||||
}
|
||||
}
|
||||
cr = fact.createLine(line, invDiff,
|
||||
C_Currency_ID, costs.negate());
|
||||
if (cr != null)
|
||||
{
|
||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
cr.setQty(line.getQty().negate());
|
||||
if (line.getC_Charge_ID() != 0) // explicit overwrite for charge
|
||||
cr.setAD_Org_ID(line.getAD_Org_ID());
|
||||
|
||||
if (isReversal(line))
|
||||
{
|
||||
// Set AmtAcctCr from Original Phys.Inventory
|
||||
if (!cr.updateReverseLine (MInventory.Table_ID,
|
||||
m_Reversal_ID, line.getReversalLine_ID(),Env.ONE))
|
||||
{
|
||||
p_Error = "Original Physical Inventory not posted yet";
|
||||
return null;
|
||||
}
|
||||
costs = cr.getAcctBalance(); //get original cost
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// InventoryDiff DR CR
|
||||
// or Charge
|
||||
MAccount invDiff = null;
|
||||
if (isReversal(line)
|
||||
&& line.getC_Charge_ID() != 0) {
|
||||
invDiff = line.getChargeAccount(as, costs);
|
||||
} else {
|
||||
invDiff = line.getChargeAccount(as, costs.negate());
|
||||
}
|
||||
|
||||
if (invDiff == null)
|
||||
invDiff = getAccount(Doc.ACCTTYPE_InvDifferences, as);
|
||||
cr = fact.createLine(line, invDiff,
|
||||
as.getC_Currency_ID(), costs.negate());
|
||||
if (cr == null)
|
||||
continue;
|
||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
cr.setQty(line.getQty().negate());
|
||||
if (line.getC_Charge_ID() != 0) // explicit overwrite for charge
|
||||
cr.setAD_Org_ID(line.getAD_Org_ID());
|
||||
|
||||
if (isReversal(line))
|
||||
if (doPosting || costAdjustment)
|
||||
{
|
||||
// Set AmtAcctCr from Original Phys.Inventory
|
||||
if (!cr.updateReverseLine (MInventory.Table_ID,
|
||||
m_Reversal_ID, line.getReversalLine_ID(),Env.ONE))
|
||||
BigDecimal costDetailAmt = costAdjustment ? adjustmentDiff : costs;
|
||||
if (costAdjustment && getC_Currency_ID() > 0 && getC_Currency_ID() != as.getC_Currency_ID())
|
||||
{
|
||||
p_Error = "Original Physical Inventory not posted yet";
|
||||
costDetailAmt = MConversionRate.convert (getCtx(),
|
||||
costDetailAmt, getC_Currency_ID(), as.getC_Currency_ID(),
|
||||
getDateAcct(), 0, getAD_Client_ID(), getAD_Org_ID());
|
||||
}
|
||||
// Cost Detail
|
||||
if (!MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costDetailAmt, line.getQty(),
|
||||
line.getDescription(), getTrxName()))
|
||||
{
|
||||
p_Error = "Failed to create cost detail record";
|
||||
return null;
|
||||
}
|
||||
costs = cr.getAcctBalance(); //get original cost
|
||||
}
|
||||
|
||||
// Cost Detail
|
||||
if (!MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs, line.getQty(),
|
||||
line.getDescription(), getTrxName()))
|
||||
{
|
||||
p_Error = "Failed to create cost detail record";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//
|
||||
|
|
|
@ -133,6 +133,19 @@ public interface I_M_Inventory
|
|||
|
||||
public org.compiere.model.I_C_DocType getC_DocType() throws RuntimeException;
|
||||
|
||||
/** Column name CostingMethod */
|
||||
public static final String COLUMNNAME_CostingMethod = "CostingMethod";
|
||||
|
||||
/** Set Costing Method.
|
||||
* Indicates how Costs will be calculated
|
||||
*/
|
||||
public void setCostingMethod (String CostingMethod);
|
||||
|
||||
/** Get Costing Method.
|
||||
* Indicates how Costs will be calculated
|
||||
*/
|
||||
public String getCostingMethod();
|
||||
|
||||
/** Column name C_Project_ID */
|
||||
public static final String COLUMNNAME_C_Project_ID = "C_Project_ID";
|
||||
|
||||
|
|
|
@ -93,6 +93,19 @@ public interface I_M_InventoryLine
|
|||
*/
|
||||
public int getCreatedBy();
|
||||
|
||||
/** Column name CurrentCostPrice */
|
||||
public static final String COLUMNNAME_CurrentCostPrice = "CurrentCostPrice";
|
||||
|
||||
/** Set Current Cost Price.
|
||||
* The currently used cost price
|
||||
*/
|
||||
public void setCurrentCostPrice (BigDecimal CurrentCostPrice);
|
||||
|
||||
/** Get Current Cost Price.
|
||||
* The currently used cost price
|
||||
*/
|
||||
public BigDecimal getCurrentCostPrice();
|
||||
|
||||
/** Column name Description */
|
||||
public static final String COLUMNNAME_Description = "Description";
|
||||
|
||||
|
@ -227,6 +240,19 @@ public interface I_M_InventoryLine
|
|||
|
||||
public org.compiere.model.I_M_Product getM_Product() throws RuntimeException;
|
||||
|
||||
/** Column name NewCostPrice */
|
||||
public static final String COLUMNNAME_NewCostPrice = "NewCostPrice";
|
||||
|
||||
/** Set New Cost Price.
|
||||
* New current cost price after processing of M_CostDetail
|
||||
*/
|
||||
public void setNewCostPrice (BigDecimal NewCostPrice);
|
||||
|
||||
/** Get New Cost Price.
|
||||
* New current cost price after processing of M_CostDetail
|
||||
*/
|
||||
public BigDecimal getNewCostPrice();
|
||||
|
||||
/** Column name Processed */
|
||||
public static final String COLUMNNAME_Processed = "Processed";
|
||||
|
||||
|
|
|
@ -1037,13 +1037,22 @@ public class MCostDetail extends X_M_CostDetail
|
|||
|| getPP_Cost_Collector_ID() != 0)
|
||||
{
|
||||
boolean addition = qty.signum() > 0;
|
||||
boolean adjustment = getM_InventoryLine_ID() > 0 && qty.signum() == 0 && amt.signum() != 0;
|
||||
boolean isVendorRMA = isVendorRMA();
|
||||
//
|
||||
if (ce.isAverageInvoice())
|
||||
{
|
||||
if (!isVendorRMA)
|
||||
{
|
||||
if (addition)
|
||||
if (adjustment)
|
||||
{
|
||||
String costingMethod = getM_InventoryLine().getM_Inventory().getCostingMethod();
|
||||
if (MCostElement.COSTINGMETHOD_AverageInvoice.equals(costingMethod))
|
||||
{
|
||||
cost.setWeightedAverage(amt.multiply(cost.getCurrentQty()), qty);
|
||||
}
|
||||
}
|
||||
else if (addition)
|
||||
{
|
||||
cost.setWeightedAverage(amt, qty);
|
||||
//shouldn't accumulate reversal of customer shipment qty and amt
|
||||
|
@ -1060,8 +1069,16 @@ public class MCostDetail extends X_M_CostDetail
|
|||
}
|
||||
else if (ce.isAveragePO())
|
||||
{
|
||||
if (addition)
|
||||
if (adjustment)
|
||||
{
|
||||
String costingMethod = getM_InventoryLine().getM_Inventory().getCostingMethod();
|
||||
if (MCostElement.COSTINGMETHOD_AveragePO.equals(costingMethod))
|
||||
{
|
||||
cost.setWeightedAverage(amt.multiply(cost.getCurrentQty()), qty);
|
||||
}
|
||||
}
|
||||
else if (addition)
|
||||
{
|
||||
cost.setWeightedAverage(amt, qty);
|
||||
//shouldn't accumulate reversal of customer shipment qty and amt
|
||||
if (isShipment() && !isVendorRMA())
|
||||
|
@ -1085,7 +1102,7 @@ public class MCostDetail extends X_M_CostDetail
|
|||
}
|
||||
else if (ce.isFifo() || ce.isLifo())
|
||||
{
|
||||
if (!isVendorRMA)
|
||||
if (!isVendorRMA && !adjustment)
|
||||
{
|
||||
if (addition)
|
||||
{
|
||||
|
@ -1110,19 +1127,28 @@ public class MCostDetail extends X_M_CostDetail
|
|||
if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - FiFo/Lifo - " + cost);
|
||||
}
|
||||
}
|
||||
else if (ce.isLastInvoice() && !isVendorRMA)
|
||||
else if (ce.isLastInvoice() && !isVendorRMA && !adjustment)
|
||||
{
|
||||
cost.setCurrentQty(cost.getCurrentQty().add(qty));
|
||||
if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - LastInv - " + cost);
|
||||
}
|
||||
else if (ce.isLastPOPrice() && !isVendorRMA)
|
||||
else if (ce.isLastPOPrice() && !isVendorRMA && !adjustment)
|
||||
{
|
||||
cost.setCurrentQty(cost.getCurrentQty().add(qty));
|
||||
if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - LastPO - " + cost);
|
||||
}
|
||||
else if (ce.isStandardCosting() && !isVendorRMA)
|
||||
{
|
||||
if (addition)
|
||||
if (adjustment)
|
||||
{
|
||||
String costingMethod = getM_InventoryLine().getM_Inventory().getCostingMethod();
|
||||
if (MCostElement.COSTINGMETHOD_StandardCosting.equals(costingMethod))
|
||||
{
|
||||
cost.add(amt.multiply(cost.getCurrentQty()), qty);
|
||||
cost.setCurrentCostPrice(cost.getCurrentCostPrice().add(amt));
|
||||
}
|
||||
}
|
||||
else if (addition)
|
||||
{
|
||||
cost.add(amt, qty);
|
||||
// Initial
|
||||
|
@ -1140,7 +1166,7 @@ public class MCostDetail extends X_M_CostDetail
|
|||
}
|
||||
if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - Standard - " + cost);
|
||||
}
|
||||
else if (ce.isUserDefined() && !isVendorRMA)
|
||||
else if (ce.isUserDefined() && !isVendorRMA && !adjustment)
|
||||
{
|
||||
// Interface
|
||||
if (addition)
|
||||
|
@ -1151,7 +1177,7 @@ public class MCostDetail extends X_M_CostDetail
|
|||
}
|
||||
else if (!ce.isCostingMethod())
|
||||
{
|
||||
// Should not happen
|
||||
//Should not happen
|
||||
if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - ?none? - " + cost);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -105,6 +105,27 @@ public class MCostElement extends X_M_CostElement
|
|||
return retValue;
|
||||
} // getMaterialCostElement
|
||||
|
||||
/**
|
||||
* Get first Material Cost Element
|
||||
* @param ctx context
|
||||
* @param CostingMethod costing method
|
||||
* @return Cost Element or null
|
||||
*/
|
||||
public static MCostElement getMaterialCostElement(Properties ctx, String CostingMethod, int AD_Org_ID)
|
||||
{
|
||||
final String whereClause = "AD_Client_ID=? AND CostingMethod=? AND CostElementType=? AND AD_Org_ID In (0, ?)";
|
||||
List<MCostElement> list = new Query(ctx, I_M_CostElement.Table_Name, whereClause, null)
|
||||
.setParameters(Env.getAD_Client_ID(ctx),CostingMethod,COSTELEMENTTYPE_Material,AD_Org_ID)
|
||||
.setOrderBy(I_M_CostElement.COLUMNNAME_AD_Org_ID + " Desc")
|
||||
.list();
|
||||
MCostElement retValue = null;
|
||||
if (list.size() > 0)
|
||||
retValue = list.get(0);
|
||||
if (list.size() > 1)
|
||||
if (s_log.isLoggable(Level.INFO)) s_log.info("More then one Material Cost Element for CostingMethod=" + CostingMethod);
|
||||
return retValue;
|
||||
} // getMaterialCostElement
|
||||
|
||||
/**
|
||||
* Get active Material Cost Element for client
|
||||
* @param po parent
|
||||
|
|
|
@ -412,6 +412,21 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
qtyDiff = line.getQtyInternalUse().negate();
|
||||
else if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
|
||||
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
|
||||
else if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(docSubTypeInv))
|
||||
{
|
||||
if (!isReversal())
|
||||
{
|
||||
BigDecimal currentCost = line.getCurrentCostPrice();
|
||||
MClient client = MClient.get(getCtx(), getAD_Client_ID());
|
||||
MAcctSchema as = client.getAcctSchema();
|
||||
MCost cost = product.getCostingRecord(as, getAD_Org_ID(), line.getM_AttributeSetInstance_ID(), getCostingMethod());
|
||||
if (cost != null && cost.getCurrentCostPrice().compareTo(currentCost) != 0)
|
||||
{
|
||||
m_processMsg = "Current Cost for Line " + line.getLine() + " have changed.";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If Quantity Count minus Quantity Book = Zero, then no change in Inventory
|
||||
if (qtyDiff.signum() == 0)
|
||||
|
|
|
@ -346,7 +346,33 @@ public class MInventoryLine extends X_M_InventoryLine
|
|||
log.saveError("Quantity", Msg.getElement(getCtx(), COLUMNNAME_QtyInternalUse));
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(docSubTypeInv)) {
|
||||
if (getNewCostPrice().signum() == 0) {
|
||||
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_NewCostPrice));
|
||||
return false;
|
||||
}
|
||||
|
||||
int M_ASI_ID = getM_AttributeSetInstance_ID();
|
||||
MProduct product = getProduct();
|
||||
MClient client = MClient.get(getCtx());
|
||||
MAcctSchema as = client.getAcctSchema();
|
||||
String costingLevel = product.getCostingLevel(as);
|
||||
if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(costingLevel)) {
|
||||
if (M_ASI_ID == 0) {
|
||||
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstance_ID));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String costingMethod = getParent().getCostingMethod();
|
||||
int AD_Org_ID = getAD_Org_ID();
|
||||
MCost cost = product.getCostingRecord(as, AD_Org_ID, M_ASI_ID, costingMethod);
|
||||
if (cost == null) {
|
||||
if (!MCostElement.COSTINGMETHOD_StandardCosting.equals(costingMethod)) {
|
||||
log.saveError("NoCostingRecord", "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.saveError("Error", "Document inventory subtype not configured, cannot complete");
|
||||
return false;
|
||||
|
|
|
@ -869,4 +869,34 @@ public class MProduct extends X_M_Product
|
|||
}
|
||||
return costingMethod;
|
||||
}
|
||||
|
||||
public MCost getCostingRecord(MAcctSchema as, int AD_Org_ID, int M_ASI_ID)
|
||||
{
|
||||
return getCostingRecord(as, AD_Org_ID, M_ASI_ID, getCostingMethod(as));
|
||||
}
|
||||
|
||||
public MCost getCostingRecord(MAcctSchema as, int AD_Org_ID, int M_ASI_ID, String costingMethod)
|
||||
{
|
||||
|
||||
String costingLevel = getCostingLevel(as);
|
||||
if (MAcctSchema.COSTINGLEVEL_Client.equals(costingLevel))
|
||||
{
|
||||
AD_Org_ID = 0;
|
||||
M_ASI_ID = 0;
|
||||
}
|
||||
else if (MAcctSchema.COSTINGLEVEL_Organization.equals(costingLevel))
|
||||
M_ASI_ID = 0;
|
||||
else if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(costingLevel))
|
||||
{
|
||||
AD_Org_ID = 0;
|
||||
if (M_ASI_ID == 0)
|
||||
return null;
|
||||
}
|
||||
MCostElement ce = MCostElement.getMaterialCostElement(getCtx(), costingMethod, AD_Org_ID);
|
||||
if (ce == null) {
|
||||
return null;
|
||||
}
|
||||
MCost cost = MCost.get(this, M_ASI_ID, as, AD_Org_ID, ce.getM_CostElement_ID(), (String)null);
|
||||
return cost.is_new() ? null : cost;
|
||||
}
|
||||
} // MProduct
|
||||
|
|
|
@ -683,11 +683,15 @@ public final class MSetup
|
|||
createDocType("Material Movement", Msg.getElement(m_ctx, "M_Movement_ID", false),
|
||||
MDocType.DOCBASETYPE_MaterialMovement, null, 0, 0, 610000, GL_MM, false);
|
||||
createDocType("Physical Inventory", Msg.getElement(m_ctx, "M_Inventory_ID", false),
|
||||
MDocType.DOCBASETYPE_MaterialPhysicalInventory, null, 0, 0, 620000, GL_MM, false);
|
||||
MDocType.DOCBASETYPE_MaterialPhysicalInventory, MDocType.DOCSUBTYPEINV_PhysicalInventory, 0, 0, 620000, GL_MM, false);
|
||||
createDocType("Material Production", Msg.getElement(m_ctx, "M_Production_ID", false),
|
||||
MDocType.DOCBASETYPE_MaterialProduction, null, 0, 0, 630000, GL_MM, false);
|
||||
createDocType("Project Issue", Msg.getElement(m_ctx, "C_ProjectIssue_ID", false),
|
||||
MDocType.DOCBASETYPE_ProjectIssue, null, 0, 0, 640000, GL_MM, false);
|
||||
createDocType("Internal Use Inventory", "Internal Use Inventory",
|
||||
MDocType.DOCBASETYPE_MaterialPhysicalInventory, MDocType.DOCSUBTYPEINV_InternalUseInventory, 0, 0, 650000, GL_MM, false);
|
||||
createDocType("Cost Adjustment", "Cost Adjustment",
|
||||
MDocType.DOCBASETYPE_MaterialPhysicalInventory, MDocType.DOCSUBTYPEINV_CostAdjustment, 0, 0, 660000, GL_MM, false);
|
||||
|
||||
// Order Entry
|
||||
createDocType("Binding offer", "Quotation",
|
||||
|
@ -891,7 +895,16 @@ public final class MSetup
|
|||
if (PrintName != null && PrintName.length() > 0)
|
||||
dt.setPrintName(PrintName); // Defaults to Name
|
||||
if (DocSubTypeSO != null)
|
||||
dt.setDocSubTypeSO(DocSubTypeSO);
|
||||
{
|
||||
if (MDocType.DOCBASETYPE_MaterialPhysicalInventory.equals(DocBaseType))
|
||||
{
|
||||
dt.setDocSubTypeInv(DocSubTypeSO);
|
||||
}
|
||||
else
|
||||
{
|
||||
dt.setDocSubTypeSO(DocSubTypeSO);
|
||||
}
|
||||
}
|
||||
if (C_DocTypeShipment_ID != 0)
|
||||
dt.setC_DocTypeShipment_ID(C_DocTypeShipment_ID);
|
||||
if (C_DocTypeInvoice_ID != 0)
|
||||
|
|
|
@ -30,7 +30,7 @@ public class X_C_DocType extends PO implements I_C_DocType, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20130626L;
|
||||
private static final long serialVersionUID = 20130717L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_C_DocType (Properties ctx, int C_DocType_ID, String trxName)
|
||||
|
@ -429,6 +429,8 @@ public class X_C_DocType extends PO implements I_C_DocType, I_Persistent
|
|||
public static final String DOCSUBTYPEINV_PhysicalInventory = "PI";
|
||||
/** Internal Use Inventory = IU */
|
||||
public static final String DOCSUBTYPEINV_InternalUseInventory = "IU";
|
||||
/** Cost Adjustment = CA */
|
||||
public static final String DOCSUBTYPEINV_CostAdjustment = "CA";
|
||||
/** Set Inv Sub Type.
|
||||
@param DocSubTypeInv
|
||||
Inventory Sub Type
|
||||
|
|
|
@ -33,7 +33,7 @@ public class X_M_Inventory extends PO implements I_M_Inventory, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20130626L;
|
||||
private static final long serialVersionUID = 20130717L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_M_Inventory (Properties ctx, int M_Inventory_ID, String trxName)
|
||||
|
@ -212,6 +212,44 @@ public class X_M_Inventory extends PO implements I_M_Inventory, I_Persistent
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** CostingMethod AD_Reference_ID=122 */
|
||||
public static final int COSTINGMETHOD_AD_Reference_ID=122;
|
||||
/** Standard Costing = S */
|
||||
public static final String COSTINGMETHOD_StandardCosting = "S";
|
||||
/** Average PO = A */
|
||||
public static final String COSTINGMETHOD_AveragePO = "A";
|
||||
/** Lifo = L */
|
||||
public static final String COSTINGMETHOD_Lifo = "L";
|
||||
/** Fifo = F */
|
||||
public static final String COSTINGMETHOD_Fifo = "F";
|
||||
/** Last PO Price = p */
|
||||
public static final String COSTINGMETHOD_LastPOPrice = "p";
|
||||
/** Average Invoice = I */
|
||||
public static final String COSTINGMETHOD_AverageInvoice = "I";
|
||||
/** Last Invoice = i */
|
||||
public static final String COSTINGMETHOD_LastInvoice = "i";
|
||||
/** User Defined = U */
|
||||
public static final String COSTINGMETHOD_UserDefined = "U";
|
||||
/** _ = x */
|
||||
public static final String COSTINGMETHOD__ = "x";
|
||||
/** Set Costing Method.
|
||||
@param CostingMethod
|
||||
Indicates how Costs will be calculated
|
||||
*/
|
||||
public void setCostingMethod (String CostingMethod)
|
||||
{
|
||||
|
||||
set_Value (COLUMNNAME_CostingMethod, CostingMethod);
|
||||
}
|
||||
|
||||
/** Get Costing Method.
|
||||
@return Indicates how Costs will be calculated
|
||||
*/
|
||||
public String getCostingMethod ()
|
||||
{
|
||||
return (String)get_Value(COLUMNNAME_CostingMethod);
|
||||
}
|
||||
|
||||
public org.compiere.model.I_C_Project getC_Project() throws RuntimeException
|
||||
{
|
||||
return (org.compiere.model.I_C_Project)MTable.get(getCtx(), org.compiere.model.I_C_Project.Table_Name)
|
||||
|
|
|
@ -32,7 +32,7 @@ public class X_M_InventoryLine extends PO implements I_M_InventoryLine, I_Persis
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20130626L;
|
||||
private static final long serialVersionUID = 20130717L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_M_InventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName)
|
||||
|
@ -111,6 +111,26 @@ public class X_M_InventoryLine extends PO implements I_M_InventoryLine, I_Persis
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** Set Current Cost Price.
|
||||
@param CurrentCostPrice
|
||||
The currently used cost price
|
||||
*/
|
||||
public void setCurrentCostPrice (BigDecimal CurrentCostPrice)
|
||||
{
|
||||
set_ValueNoCheck (COLUMNNAME_CurrentCostPrice, CurrentCostPrice);
|
||||
}
|
||||
|
||||
/** Get Current Cost Price.
|
||||
@return The currently used cost price
|
||||
*/
|
||||
public BigDecimal getCurrentCostPrice ()
|
||||
{
|
||||
BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_CurrentCostPrice);
|
||||
if (bd == null)
|
||||
return Env.ZERO;
|
||||
return bd;
|
||||
}
|
||||
|
||||
/** Set Description.
|
||||
@param Description
|
||||
Optional short description of the record
|
||||
|
@ -329,6 +349,26 @@ public class X_M_InventoryLine extends PO implements I_M_InventoryLine, I_Persis
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** Set New Cost Price.
|
||||
@param NewCostPrice
|
||||
New current cost price after processing of M_CostDetail
|
||||
*/
|
||||
public void setNewCostPrice (BigDecimal NewCostPrice)
|
||||
{
|
||||
set_Value (COLUMNNAME_NewCostPrice, NewCostPrice);
|
||||
}
|
||||
|
||||
/** Get New Cost Price.
|
||||
@return New current cost price after processing of M_CostDetail
|
||||
*/
|
||||
public BigDecimal getNewCostPrice ()
|
||||
{
|
||||
BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_NewCostPrice);
|
||||
if (bd == null)
|
||||
return Env.ZERO;
|
||||
return bd;
|
||||
}
|
||||
|
||||
/** Set Processed.
|
||||
@param Processed
|
||||
The document has been processed
|
||||
|
|
Loading…
Reference in New Issue