Contributing Inventory Test JUnit seed to ADempiere core

This commit is contained in:
teo_sarca 2009-02-12 16:47:13 +00:00
parent e6fb8decce
commit 39ebb50342
5 changed files with 1163 additions and 0 deletions

View File

@ -0,0 +1,191 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
* 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 test.functional.inventory;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.supercsv.io.CsvListReader;
import org.supercsv.io.ICsvListReader;
import org.supercsv.prefs.CsvPreference;
/**
* @author Teo Sarca, www.arhipac.ro
*/
public class CSVFactory
{
public static final DateFormat s_dateFormat = new SimpleDateFormat("dd.MM.yyyy");
private ICsvListReader reader;
public Collection<MMScenario> read(InputStream in) throws Exception
{
ArrayList<MMScenario> tests = new ArrayList<MMScenario>();
//
reader = new CsvListReader(new InputStreamReader(in), CsvPreference.STANDARD_PREFERENCE);
String[] header = getCSVHeader();
//
List<String> line;
int last_lineNo = -1;
MMScenario scenario = null;
try
{
while ( (line = reader.read()) != null)
{
if (last_lineNo == -1 || last_lineNo + 1 < reader.getLineNumber())
{
if (scenario != null)
{
tests.add(scenario);
}
scenario = new MMScenario("junit-test-line_"+(new DecimalFormat("000").format(reader.getLineNumber())));
}
readDocument(scenario, header, line);
last_lineNo = reader.getLineNumber();
}
}
catch (Exception e)
{
throw new RuntimeException("Error on line "+reader.getLineNumber()+": "+e.getLocalizedMessage(), e);
}
if (scenario != null)
{
tests.add(scenario);
}
//
return tests;
}
private String[] getCSVHeader() throws IOException
{
String[] header = reader.getCSVHeader(true);
for (int i = 0; i < header.length; i++)
{
header[i] = header[i].trim().replaceAll("\\s", "");
}
return header;
}
private void readDocument(MMScenario scenario, String[] header, List<String> line)
{
MMDocument doc = new MMDocument(scenario);
doc.csvLineNo = reader.getLineNumber();
doc.DocBaseType = getValue("DocType", String.class, header, line);
doc.DocumentNo = getValue("DocumentNo", String.class, header, line);
doc.LocatorValue = getValue("LocatorValue", String.class, header, line);
doc.LocatorValueTo = getValue("LocatorValueTo", String.class, header, line);
doc.ProductValue = getValue("ProductValue", String.class, header, line);
doc.Price = getValue("Price", BigDecimal.class, header, line);
doc.Qty = getValue("Qty", BigDecimal.class, header, line);
doc.QtyOrdered = getValue("QtyOrdered", BigDecimal.class, header, line);
doc.QtyReserved = getValue("QtyReserved", BigDecimal.class, header, line);
doc.ASI = getValue("ASI", String.class, header, line);
doc.Date = getValue("MovementDate", Timestamp.class, header, line);
doc.PODocumentNo = getValue("PODocumentNo", String.class, header, line);
doc.IsReversal = getValue("IsReversal", Boolean.class, header, line);
scenario.docs.add(doc);
}
/**
* TODO: refactor
* @param <T>
* @param name
* @param clazz
* @param headers
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getValue(String name, Class<T> clazz, String[] headers, List<String> values)
{
String value = null;
for (int i = 0; i < headers.length; i++)
{
if (name.equalsIgnoreCase(headers[i]))
{
if (values.size() > i)
{
value = values.get(i);
}
break;
}
}
if (value != null && value.trim().length() == 0)
{
value = null;
}
//
if (String.class == clazz)
{
return (T)value;
}
else if (BigDecimal.class == clazz)
{
if (value == null)
return (T)BigDecimal.ZERO;
else
return (T)new BigDecimal(value);
}
else if (Integer.class == clazz)
{
if (value == null)
return (T)Integer.valueOf(0);
else
return (T)((Integer)Integer.parseInt(value));
}
else if (Timestamp.class == clazz)
{
if (value == null)
return null;
else
{
try
{
Date date = s_dateFormat.parse(value);
return (T)new Timestamp(date.getTime());
}
catch(ParseException e)
{
throw new RuntimeException(e);
}
}
}
else if (Boolean.class == clazz)
{
if (value == null)
return (T)Boolean.FALSE;
else if ("Y".equals(value))
return (T)Boolean.TRUE;
else if ("N".equals(value))
return (T)Boolean.FALSE;
else
throw new IllegalStateException("Invalid boolean value '"+value+"'");
}
else
{
throw new IllegalArgumentException("clazz not supported - "+clazz);
}
}
}

View File

@ -0,0 +1,277 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
* 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 test.functional.inventory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.model.MDocType;
import org.compiere.model.MLocator;
import org.compiere.model.MProduct;
import org.compiere.model.MStorage;
import org.compiere.process.DocAction;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Trx;
import org.compiere.util.TrxRunnable;
import org.compiere.util.Util;
import test.AdempiereTestCase;
/**
* Run Inventory Tests
* @author Teo Sarca, www.arhipac.ro
*/
public class InventoryTest extends AdempiereTestCase
{
@Override
protected void setUp() throws Exception
{
super.setUp();
Env.setContext(Env.getCtx(), "$C_Currency_ID", 346);
// MLocator locator = InventoryUtil.getCreateLocator(-1, "junit-wh1", "l1");
Env.setContext(Env.getCtx(), "#M_Warehouse_ID", -1);
Env.setContext(Env.getCtx(), "#PO_PriceList_ID",
InventoryUtil.getCreatePriceList("junit-PO", false).get_ID());
Env.setContext(Env.getCtx(), "#SO_PriceList_ID",
InventoryUtil.getCreatePriceList("junit-SO", true).get_ID());
}
public void test01() throws Exception
{
InputStream in;
if (System.getProperty("TestFile") != null)
{
in = new FileInputStream(System.getProperty("TestFile"));
}
else //if (System.getProperty("UseArhipacURL") != null)
{
String url = "http://spreadsheets.google.com/pub?key=p_F3GDtQxWTA9YbH8MRkyKA&output=csv&gid=0";
in = new URL(url).openStream();
}
//
CSVFactory factory = new CSVFactory();
Collection<MMScenario> tests = factory.read(in);
String trxName = getTrxName();
//
for (MMScenario scenario : tests)
{
if ("junit-test-line_053".compareTo(scenario.name) <= 0)
runMMScenario(scenario, trxName);
// break;
}
}
private void runMMScenario(MMScenario scenario, String trxName)
{
scenario.key = ""+System.currentTimeMillis();
for (MMDocument doc : scenario.docs)
{
boolean ok = false;
try
{
createDocument(doc, trxName);
ok = true;
}
catch (Exception e)
{
InventoryTestException ie = (e instanceof InventoryTestException ? (InventoryTestException)e : new InventoryTestException(e));
ie.scenario = scenario;
ie.document = doc;
throw ie;
}
finally
{
if (!ok)
{
dumpStatus(doc, trxName);
try
{
commit();
}
catch (Exception e){}
}
}
}
}
private void createDocument(final MMDocument doc, String trxName)
{
Trx.run(trxName, new TrxRunnable(){
@Override
public void run(String trxName) {
if (doc.IsReversal)
{
MMDocument docOrig = doc.scenario.get(doc.DocBaseType, doc.DocumentNo);
doc.ProductValue = docOrig.ProductValue;
doc.LocatorValue = docOrig.LocatorValue;
doc.LocatorValueTo = docOrig.LocatorValueTo;
InventoryUtil.processDocument(docOrig, DocAction.ACTION_Reverse_Correct, DocAction.STATUS_Reversed);
return;
}
if (doc.ProductValue == null)
throw new RuntimeException("ProductValue is null");
doc.ProductValue = "junit-"+doc.ProductValue+"-"+doc.scenario.key;
// Check document No conflict
if (doc.scenario.get(doc.DocBaseType, doc.DocumentNo) != null)
{
throw new AdempiereException("DocumentNo conflict - "+doc.DocumentNo);
}
if (MDocType.DOCBASETYPE_PurchaseOrder.equals(doc.DocBaseType)
|| MDocType.DOCBASETYPE_SalesOrder.equals(doc.DocBaseType) )
{
InventoryUtil.createOrder(doc, trxName);
}
else if (MDocType.DOCBASETYPE_MaterialReceipt.equals(doc.DocBaseType)
|| MDocType.DOCBASETYPE_MaterialDelivery.equals(doc.DocBaseType) )
{
InventoryUtil.createInOut(doc, trxName);
}
else if (MDocType.DOCBASETYPE_MaterialMovement.equals(doc.DocBaseType))
{
InventoryUtil.createMovement(doc, trxName);
}
else if (MDocType.DOCBASETYPE_MaterialPhysicalInventory.equals(doc.DocBaseType))
{
InventoryUtil.createInventory(doc, trxName);
}
else if ("TST".equals(doc.DocBaseType))
{
assertStorage(doc, trxName);
}
else
{
throw new AdempiereException("DocBaseType not supported for "+doc);
}
}});
}
private void assertStorage(MMDocument doc, String trxName)
{
MLocator locator = InventoryUtil.getCreateLocator(-1, doc.LocatorValue, doc.LocatorValue);
MProduct product = InventoryUtil.getCreateProduct(doc.ProductValue, null);
int M_ASI_ID = -1;
if (!Util.isEmpty(doc.ASI, true))
{
M_ASI_ID = doc.scenario.getM_ASI_ID(doc.ASI);
}
ArrayList<Object> params = new ArrayList<Object>();
String sql = "SELECT"
+" COALESCE(SUM(QtyOnHand),0)"
+",COALESCE(SUM(QtyReserved),0)"
+",COALESCE(SUM(QtyOrdered),0)"
+" FROM M_Storage"
+" WHERE M_Locator_ID=? AND M_Product_ID=?";
params.add(locator.get_ID());
params.add(product.get_ID());
if (M_ASI_ID >= 0)
{
sql += " AND "+MStorage.COLUMNNAME_M_AttributeSetInstance_ID+"=?";
params.add(M_ASI_ID);
}
PreparedStatement pstmt = null;
ResultSet rs = null;
BigDecimal qtyOnHand = Env.ZERO;
BigDecimal qtyOrdered = Env.ZERO;
BigDecimal qtyReserved = Env.ZERO;
try
{
pstmt = DB.prepareStatement(sql, trxName);
DB.setParameters(pstmt, params);
rs = pstmt.executeQuery();
if (rs.next())
{
qtyOnHand = rs.getBigDecimal(1);
qtyReserved = rs.getBigDecimal(2);
qtyOrdered = rs.getBigDecimal(3);
}
}
catch (SQLException e)
{
throw new DBException(e, sql);
}
finally
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
//
//
assertEquals("QtyOnHand not match "+doc, doc.Qty, qtyOnHand);
assertEquals("QtyReserved not match "+doc, doc.QtyReserved, qtyReserved);
assertEquals("QtyOrdered not match "+doc, doc.QtyOrdered, qtyOrdered);
}
private void dumpStatus(MMDocument doc, String trxName)
{
MProduct product = InventoryUtil.getCreateProduct(doc.ProductValue, null);
MStorage[] storage = MStorage.getOfProduct(getCtx(), product.get_ID(), trxName);
System.err.println("STORAGE____________________________________________________");
System.err.println(" "+doc);
for (MStorage s : storage)
{
System.err.println(""+s);
}
//
System.err.println(doc.scenario.toString());
//
System.err.println("___________________________________________________________");
System.err.flush();
System.err.flush();
}
}
class InventoryTestException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public MMScenario scenario = null;
public MMDocument document = null;
public InventoryTestException(Exception e)
{
super(e);
}
@Override
public String getMessage()
{
String retValue = "";
retValue = super.getMessage()
+ "\n document=" + this.document
+ "\n scenario=" + this.scenario
;
return retValue;
}
}

View File

@ -0,0 +1,502 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
* 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 test.functional.inventory;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Properties;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.MBPGroup;
import org.compiere.model.MBPartner;
import org.compiere.model.MBPartnerLocation;
import org.compiere.model.MCharge;
import org.compiere.model.MDocType;
import org.compiere.model.MInOut;
import org.compiere.model.MInOutLine;
import org.compiere.model.MInventory;
import org.compiere.model.MInventoryLine;
import org.compiere.model.MLocation;
import org.compiere.model.MLocator;
import org.compiere.model.MMovement;
import org.compiere.model.MMovementLine;
import org.compiere.model.MOrder;
import org.compiere.model.MOrderLine;
import org.compiere.model.MPriceList;
import org.compiere.model.MPriceListVersion;
import org.compiere.model.MProduct;
import org.compiere.model.MProductCategory;
import org.compiere.model.MProductPrice;
import org.compiere.model.MTaxCategory;
import org.compiere.model.MWarehouse;
import org.compiere.model.PO;
import org.compiere.model.Query;
import org.compiere.process.DocAction;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.TimeUtil;
import org.compiere.util.Util;
/**
* @author Teo Sarca, www.arhipac.ro
*/
public final class InventoryUtil
{
public static MProduct getCreateProduct(String value, String MMPolicy)
{
Properties ctx = Env.getCtx();
MProduct product = new Query(ctx, MProduct.Table_Name, "Value=?", null)
.setParameters(new Object[]{value})
.setOnlyActiveRecords(true)
.setClient_ID()
.firstOnly();
if (product == null)
{
product = new MProduct(ctx, 0, null);
}
product.setValue(value);
product.setName(value);
setGeneratedTag(product);
product.setProductType(MProduct.PRODUCTTYPE_Item);
product.setIsStocked(true);
product.setC_UOM_ID(100); // Each
product.setC_TaxCategory_ID(getDefault_TaxCategory_ID());
product.setM_Product_Category_ID(getCreateProductCategory(value, MMPolicy).get_ID());
product.saveEx();
//
getCreateProductPrice("#PO_PriceList_ID", product.get_ID(), 10);
getCreateProductPrice("#SO_PriceList_ID", product.get_ID(), 20);
//
return product;
}
public static MProductPrice getCreateProductPrice (String ctxPriceList, int M_Product_ID, int price)
{
Properties ctx = Env.getCtx();
int M_PriceList_ID = Env.getContextAsInt(ctx, ctxPriceList);
MPriceList pl = MPriceList.get(ctx, M_PriceList_ID, null);
MPriceListVersion plv = pl.getPriceListVersion(null);
//
BigDecimal priceBD = BigDecimal.valueOf(price);
MProductPrice pp = MProductPrice.get(ctx, plv.get_ID(), M_Product_ID, null);
if (pp == null)
{
pp = new MProductPrice(plv, M_Product_ID, priceBD, priceBD, priceBD);
}
pp.setPrices(priceBD, priceBD, priceBD);
pp.saveEx();
return pp;
}
public static MProductCategory getCreateProductCategory(String value, String MMPolicy)
{
if (MMPolicy == null)
MMPolicy = MProductCategory.MMPOLICY_FiFo;
Properties ctx = Env.getCtx();
String whereClause = MProductCategory.COLUMNNAME_Value+"=?";
MProductCategory pc = new Query(ctx, MProductCategory.Table_Name, whereClause, null)
.setParameters(new Object[]{value})
.setOnlyActiveRecords(true)
.setClient_ID()
.firstOnly();
if (pc == null)
{
pc = new MProductCategory(ctx, 0, null);
}
pc.setValue(value);
pc.setName(value);
setGeneratedTag(pc);
pc.setMMPolicy(MMPolicy);
//
pc.saveEx();
return pc;
}
public static int getDefault_TaxCategory_ID()
{
Properties ctx = Env.getCtx();
return new Query(ctx, MTaxCategory.Table_Name, "IsDefault='Y'", null)
.setClient_ID()
.setOnlyActiveRecords(true)
.firstOnly()
.get_ID();
}
public static MBPartner getCreatePartner(String value)
{
Properties ctx = Env.getCtx();
String whereClause = MBPartner.COLUMNNAME_Value+"=?";
MBPartner bp = new Query(ctx, MBPartner.Table_Name, whereClause, null)
.setParameters(new Object[]{value})
.setClient_ID()
.firstOnly();
if (bp == null)
{
bp = new MBPartner(ctx, 0, null);
}
bp.setValue(value);
bp.setName(value);
setGeneratedTag(bp);
bp.setIsCustomer(true);
bp.setIsVendor(true);
bp.setC_BP_Group_ID(MBPGroup.getDefault(ctx).get_ID());
bp.saveEx();
//
if (bp.getLocations(false).length == 0)
{
MLocation loc = new MLocation(ctx, 0, null);
loc.saveEx();
//
MBPartnerLocation bpl = new MBPartnerLocation(bp);
bpl.setC_Location_ID(loc.get_ID());
bpl.saveEx();
}
return bp;
}
public static MOrder createOrder(MMDocument doc, String trxName)
{
Properties ctx = Env.getCtx();
int M_PriceList_ID;
boolean isSOTrx;
if (MDocType.DOCBASETYPE_SalesOrder.equals(doc.DocBaseType))
{
M_PriceList_ID = Env.getContextAsInt(ctx, "SO_PriceList_ID");
isSOTrx = true;
}
else if (MDocType.DOCBASETYPE_PurchaseOrder.equals(doc.DocBaseType))
{
M_PriceList_ID = Env.getContextAsInt(ctx, "PO_PriceList_ID");
isSOTrx = false;
}
else
{
throw new IllegalArgumentException("DocBaseType not supported - "+doc);
}
//
int AD_Org_ID = getFirst_Org_ID();
MLocator locator = getCreateLocator(AD_Org_ID, doc.LocatorValue, doc.LocatorValue);
//
MOrder order = new MOrder(ctx, 0, trxName);
order.setAD_Org_ID(AD_Org_ID);
order.setIsSOTrx(isSOTrx);
order.setC_DocTypeTarget_ID();
order.setDateOrdered(doc.Date);
order.setDateAcct(doc.Date);
order.setDatePromised(doc.Date);
order.setBPartner(getCreatePartner(doc.BPValue));
order.setM_PriceList_ID(M_PriceList_ID);
order.setM_Warehouse_ID(locator.getM_Warehouse_ID());
setGeneratedTag(order);
order.saveEx();
//
MProduct product = getCreateProduct(doc.ProductValue, null);
MOrderLine line = new MOrderLine(order);
line.setProduct(product);
line.setQty(doc.Qty);
line.saveEx();
//
doc.document = order;
processDocument(doc, MOrder.DOCACTION_Complete, MOrder.DOCSTATUS_Completed);
return order;
}
public static MInOut createInOut(MMDocument doc, String trxName)
{
MOrder order;
if (MDocType.DOCBASETYPE_MaterialReceipt.equals(doc.DocBaseType))
{
order = (MOrder)doc.scenario.get(MDocType.DOCBASETYPE_PurchaseOrder, doc.PODocumentNo).document;
}
else if (MDocType.DOCBASETYPE_MaterialDelivery.equals(doc.DocBaseType))
{
order = (MOrder)doc.scenario.get(MDocType.DOCBASETYPE_SalesOrder, doc.PODocumentNo).document;
}
else
{
throw new IllegalArgumentException("DocBaseType not supported - "+doc);
}
// if (trxName != null && trxName.equals(order.get_TrxName()))
// throw new AdempiereException("Internal exception - not same trxName");
MInOut io = new MInOut(order, 0, doc.Date);
setGeneratedTag(io);
io.saveEx();
//
MInOutLine iol = null;
for (MOrderLine oline : order.getLines(true, null))
{
iol = new MInOutLine(io);
iol.setOrderLine(oline, 0, doc.Qty);
iol.setQty(doc.Qty);
iol.saveEx();
break;
}
//
doc.document = io;
processDocument(doc, MInOut.DOCACTION_Complete, MInOut.DOCSTATUS_Completed);
if (!Util.isEmpty(doc.ASI))
{
iol.load(trxName);
doc.scenario.registerASICode(doc.ASI, iol.getM_AttributeSetInstance_ID(), !io.isSOTrx());
}
return io;
}
public static MMovement createMovement(MMDocument doc, String trxName)
{
Properties ctx = Env.getCtx();
int AD_Org_ID = getFirst_Org_ID();
MProduct product = getCreateProduct(doc.ProductValue, null);
MLocator locator = getCreateLocator(AD_Org_ID, doc.LocatorValue, doc.LocatorValue);
MLocator locatorTo = getCreateLocator(AD_Org_ID, doc.LocatorValueTo, doc.LocatorValueTo);
//
MMovement m = new MMovement(ctx, 0, trxName);
m.setAD_Org_ID(AD_Org_ID);
m.setMovementDate(doc.Date);
m.saveEx();
//
MMovementLine line = new MMovementLine(m);
line.setM_Product_ID(product.get_ID());
line.setM_Locator_ID(locator.get_ID());
line.setM_LocatorTo_ID(locatorTo.get_ID());
line.setMovementQty(doc.Qty);
line.saveEx();
//
doc.document = m;
processDocument(doc, MMovement.DOCACTION_Complete, MMovement.DOCSTATUS_Completed);
return m;
}
public static MInventory createInventory(MMDocument doc, String trxName)
{
Properties ctx = Env.getCtx();
int AD_Org_ID = getFirst_Org_ID();
MProduct product = getCreateProduct(doc.ProductValue, null);
MLocator locator = getCreateLocator(AD_Org_ID, doc.LocatorValue, doc.LocatorValue);
//
MInventory inv = new MInventory(ctx, 0, trxName);
inv.setAD_Org_ID(AD_Org_ID);
// inv.setIsInternalUseInventory(true);
inv.setMovementDate(doc.Date);
inv.setM_Warehouse_ID(locator.getM_Warehouse_ID());
setGeneratedTag(inv);
inv.saveEx();
//
MInventoryLine line = new MInventoryLine(inv,
locator.get_ID(), product.get_ID(), 0,
null, null);
line.setQtyInternalUse(doc.Qty);
line.setC_Charge_ID(getCreateCharge("junit-charge").get_ID());
line.saveEx();
//
doc.document = inv;
processDocument(doc, MInventory.DOCACTION_Complete, MInventory.DOCSTATUS_Completed);
if (!Util.isEmpty(doc.ASI))
{
line.load(trxName);
doc.scenario.registerASICode(doc.ASI, line.getM_AttributeSetInstance_ID(), line.getQtyInternalUse().signum() <= 0);
}
return inv;
}
public static int getFirst_Org_ID()
{
int AD_Org_ID = Env.getAD_Org_ID(Env.getCtx());
if (AD_Org_ID > 0)
return AD_Org_ID;
String sql = "SELECT MIN(AD_Org_ID) FROM AD_Org WHERE AD_Client_ID=?";
return DB.getSQLValueEx(null, sql, Env.getAD_Client_ID(Env.getCtx()));
}
/**
* Helper Method : Create Warehouse
*/
public static MWarehouse getCreateWarehouse(int AD_Org_ID, String value)
{
if (AD_Org_ID <= 0)
AD_Org_ID = getFirst_Org_ID();
Properties ctx = Env.getCtx();
String whereClause = "AD_Org_ID=? AND Value=?";
MWarehouse wh = new Query(ctx, MWarehouse.Table_Name, whereClause, null)
.setParameters(new Object[]{AD_Org_ID, value})
.setClient_ID()
.firstOnly();
if (wh != null)
return wh;
wh = new MWarehouse(ctx, 0, null);
wh.setAD_Org_ID(AD_Org_ID);
wh.setValue(value);
wh.setName(value);
MLocation loc = new MLocation(ctx, 0, null);
loc.saveEx();
wh.setC_Location_ID(loc.get_ID());
wh.saveEx();
return wh;
}
/**
* Helper Method : Create Locator
*/
public static MLocator getCreateLocator(int AD_Org_ID, String whValue, String value)
{
if (AD_Org_ID <= 0)
AD_Org_ID = getFirst_Org_ID();
MWarehouse wh = getCreateWarehouse(AD_Org_ID, whValue);
MLocator locator = null;
for (MLocator loc : wh.getLocators(false))
{
if (loc.getValue().equals(value))
{
locator = loc;
break;
}
}
if (locator == null)
{
locator = new MLocator(wh, value);
locator.setXYZ(value, value, value);
}
if (wh.getLocators(false).length == 0)
{
locator.setIsDefault(true);
}
locator.saveEx();
//
return locator;
}
public static MPriceList getCreatePriceList(String value, boolean IsSOPriceList)
{
Properties ctx = Env.getCtx();
int C_Currency_ID = Env.getContextAsInt(ctx, "$C_Currency_ID");
String whereClause = MPriceList.COLUMNNAME_Name+"=?"
+" AND "+MPriceList.COLUMNNAME_IsSOPriceList+"=?"
+" AND "+MPriceList.COLUMNNAME_C_Currency_ID+"=?";
MPriceList pl = new Query(ctx, MPriceList.Table_Name, whereClause, null)
.setParameters(new Object[]{value, IsSOPriceList, C_Currency_ID})
.setClient_ID()
.setOnlyActiveRecords(true)
.firstOnly();
if (pl == null)
{
pl = new MPriceList(ctx, 0, null);
pl.setName(value);
pl.setIsSOPriceList(IsSOPriceList);
pl.setC_Currency_ID(C_Currency_ID);
}
setGeneratedTag(pl);
pl.setIsTaxIncluded(false);
pl.saveEx();
//
Timestamp ValidFrom = TimeUtil.getDay(1970, 1, 1);
MPriceListVersion plv = pl.getPriceListVersion(ValidFrom);
if (plv == null)
{
plv = new MPriceListVersion(pl);
plv.setValidFrom(ValidFrom);
plv.setM_DiscountSchema_ID(getM_DiscountSchema_ID());
setGeneratedTag(plv);
plv.saveEx();
}
//
return pl;
}
public static int getM_DiscountSchema_ID()
{
Properties ctx = Env.getCtx();
int AD_Client_ID = Env.getAD_Client_ID(ctx);
final String sql = "SELECT MIN(M_DiscountSchema_ID) FROM M_DiscountSchema" +
" WHERE AD_Client_ID=?";
return DB.getSQLValueEx(null, sql, AD_Client_ID);
}
public static void setGeneratedTag(PO po)
{
String desc = "Generated by "+InventoryUtil.class
+" on "+new Timestamp(System.currentTimeMillis());
po.set_ValueOfColumn("Description", desc);
}
public static void processDocument(MMDocument doc,
String docAction, String targetDocStatus)
{
PO po = (PO)doc.document;
// po.saveEx();
po.load(po.get_TrxName());
po.set_ValueOfColumn("DocAction", docAction);
//
try
{
if (!doc.document.processIt(docAction))
throw new AdempiereException(doc.document.getProcessMsg());
}
catch (Exception e)
{
throw (e instanceof AdempiereException ? (AdempiereException)e : new AdempiereException(e));
}
po.saveEx();
//
// Check DocSatus
if (targetDocStatus != null && !targetDocStatus.equals(doc.document.getDocStatus()))
{
throw new AdempiereException("Doc process error "+doc
+" (TargetDocStatus="+targetDocStatus
+", DocStatus="+doc.document.getDocStatus()
+")");
}
//
// Is Completed ?
if (DocAction.STATUS_Completed.equals(doc.document.getDocStatus()))
{
// Track ASI:
if (!Util.isEmpty(doc.ASI))
{
}
}
}
public static MCharge getCreateCharge(String value)
{
Properties ctx = Env.getCtx();
String whereClause = MCharge.COLUMNNAME_Name+"=?";
MCharge charge = new Query(ctx, MCharge.Table_Name, whereClause, null)
.setParameters(new Object[]{value})
.setOnlyActiveRecords(true)
.setClient_ID()
.firstOnly();
if (charge == null)
{
charge = new MCharge(ctx, 0, null);
charge.setName(value);
setGeneratedTag(charge);
charge.saveEx();
}
return charge;
}
}

View File

@ -0,0 +1,86 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
* 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 test.functional.inventory;
import java.math.BigDecimal;
import java.sql.Timestamp;
import org.compiere.process.DocAction;
/**
* @author Teo Sarca, www.arhipac.ro
*/
public class MMDocument
{
public final MMScenario scenario;
public int csvLineNo = -1;
public String DocBaseType;
public String DocumentNo;
public String BPValue = "junit-test-bp01";
public String LocatorValue;
public String LocatorValueTo;
public String ProductValue;
public BigDecimal Price;
public BigDecimal Qty;
public BigDecimal QtyOrdered;
public BigDecimal QtyReserved;
public Timestamp Date;
public String ASI;
public String PODocumentNo;
public boolean IsReversal = false;
//
public DocAction document = null;
public MMDocument(MMScenario scenario)
{
this.scenario = scenario;
}
/**
* Constructs a <code>String</code> with all attributes
* in name = value format.
*
* @return a <code>String</code> representation
* of this object.
*/
public String toString()
{
final String TAB = " ";
String retValue = "";
retValue = "MMDocument ( "
// + super.toString() + TAB
+ "csvLineNo = " + this.csvLineNo + TAB
+ "DocBaseType = " + this.DocBaseType + TAB
+ "DocumentNo = " + this.DocumentNo + TAB
+ "LocatorValue = " + this.LocatorValue + TAB
+ "LocatorValueTo = " + this.LocatorValueTo + TAB
+ "ProductValue = " + this.ProductValue + TAB
+ "Price = " + this.Price + TAB
+ "Qty = " + this.Qty + TAB
+ "QtyOrdered = " + this.QtyOrdered + TAB
+ "QtyReserved = " + this.QtyReserved + TAB
+ "ASI = " + this.ASI + TAB
+ "Date = " + this.Date + TAB
+ "PODocumentNo = " + this.PODocumentNo + TAB
+ "IsReversal = " + this.IsReversal + TAB
+ "document = " + this.document + TAB
+ " )";
return retValue;
}
}

View File

@ -0,0 +1,107 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. *
* 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 test.functional.inventory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import org.adempiere.exceptions.AdempiereException;
/**
* @author Teo Sarca, www.arhipac.ro
*/
public class MMScenario
{
public final String name;
public String key = null;
public final List<MMDocument> docs = new ArrayList<MMDocument>();
/** ASI Code -> M_AttributeSetInstance_ID */
public final HashMap<String, Integer> asiCodes = new HashMap<String, Integer>();
public MMScenario(String name)
{
this.name = name;
}
public MMDocument get(String docBaseType, String documentNo)
{
if (documentNo == null)
throw new IllegalArgumentException("documentNo is null");
//
for (MMDocument doc : docs)
{
if (docBaseType.equals(doc.DocBaseType) && documentNo.equals(documentNo))
return doc;
}
throw new AdempiereException("["+name+"] document not found for"
+" DocBaseType="+docBaseType+", documentNo="+documentNo);
}
public void registerASICode(String asiCode, int M_ASI_ID, boolean isCreated)
{
asiCode = asiCode.trim();
if (isCreated && asiCodes.get(asiCode) != null)
{
throw new AdempiereException("ASI Should be unique : Code="+asiCode+", ID="+M_ASI_ID);
}
asiCodes.put(asiCode, M_ASI_ID);
}
public int getM_ASI_ID(String asiCode)
{
asiCode = asiCode.trim();
if (asiCode.equals("0"))
return 0;
Integer asi_id = asiCodes.get(asiCode);
if (asi_id == null)
{
throw new AdempiereException("No ASI created for Code="+asiCode);
}
return asi_id;
}
@Override
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("__SCENARIO________________________________________________\n");
sb.append(" Name : "+this.name).append("\n");
sb.append(" Key : "+this.key).append("\n");
//
sb.append("Lines: \n");
for (MMDocument doc : this.docs)
{
sb.append(" ").append(doc.toString()).append("\n");
}
//
sb.append("ASI(Code=>ID): ");
for (Entry<String, Integer> entry : this.asiCodes.entrySet())
{
sb.append("(")
.append(entry.getKey()).append("=>").append(entry.getValue())
.append("); ");
}
sb.append("\n");
//
sb.append("__________________________________________________________\n");
return sb.toString();
}
}