libero: MRPTest was moved to libero branch
This commit is contained in:
parent
7079c102e1
commit
3f65c5be03
|
@ -1,211 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
|
||||||
* Copyright (C) 2008 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.mrp;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
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.eevolution.model.I_PP_MRP;
|
|
||||||
import org.supercsv.io.CsvListReader;
|
|
||||||
import org.supercsv.io.ICsvListReader;
|
|
||||||
import org.supercsv.prefs.CsvPreference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a CSV file and produce {@link TestableMRP} objects, ready to be run.
|
|
||||||
* @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<TestableMRP> read(InputStream in) throws Exception
|
|
||||||
{
|
|
||||||
ArrayList<TestableMRP> tests = new ArrayList<TestableMRP>();
|
|
||||||
//
|
|
||||||
reader = new CsvListReader(new InputStreamReader(in), CsvPreference.STANDARD_PREFERENCE);
|
|
||||||
String[] header = reader.getCSVHeader(true);
|
|
||||||
System.out.println("HEADER: "+MRPUtil.toString(header));
|
|
||||||
//
|
|
||||||
List<String> line;
|
|
||||||
int last_lineNo = -1;
|
|
||||||
boolean isPlanningLine = true;
|
|
||||||
TestableMRP mrpTest = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while ( (line = reader.read()) != null)
|
|
||||||
{
|
|
||||||
if (last_lineNo == -1 || last_lineNo + 1 < reader.getLineNumber())
|
|
||||||
{
|
|
||||||
isPlanningLine = true;
|
|
||||||
if (mrpTest != null)
|
|
||||||
{
|
|
||||||
tests.add(mrpTest);
|
|
||||||
}
|
|
||||||
mrpTest = new TestableMRP();
|
|
||||||
}
|
|
||||||
if (isPlanningLine)
|
|
||||||
{
|
|
||||||
readProductPlanning(mrpTest, header, line);
|
|
||||||
isPlanningLine = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
readMRPLine(mrpTest, header, line);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
last_lineNo = reader.getLineNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException("Error on line "+reader.getLineNumber()+": "+e.getLocalizedMessage(), e);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return tests;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readProductPlanning(TestableMRP mrpTest, String[] header, List<String> line)
|
|
||||||
{
|
|
||||||
mrpTest.name = "junit-test-line_"+reader.getLineNumber();
|
|
||||||
mrpTest.description = "Test starts in CSV at line "+reader.getLineNumber();
|
|
||||||
mrpTest.qtyOnHand = getValue("QtyOnHand", BigDecimal.class, header, line);
|
|
||||||
mrpTest.today = getValue("Today", Timestamp.class, header, line);
|
|
||||||
//
|
|
||||||
int LeadTime = getValue("LeadTime", Integer.class, header, line);
|
|
||||||
String Order_Policy = getValue("Order_Policy", String.class, header, line);
|
|
||||||
int Order_Min = getValue("Order_Min", Integer.class, header, line);
|
|
||||||
int Order_Pack = getValue("Order_Min", Integer.class, header, line);
|
|
||||||
int Order_Max = getValue("Order_Max", Integer.class, header, line);
|
|
||||||
int SafetyStock = getValue("SafetyStock", Integer.class, header, line);
|
|
||||||
int Order_Period = 0;
|
|
||||||
mrpTest.planning = MRPTest.getPlanning(mrpTest.productValue,
|
|
||||||
Order_Policy, Order_Min, Order_Max, Order_Pack, SafetyStock, Order_Period, LeadTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readMRPLine(TestableMRP mrpTest, String[] header, List<String> line)
|
|
||||||
{
|
|
||||||
boolean isGenerated = getValue("Generated", Boolean.class, header, line);
|
|
||||||
Timestamp DatePromised = getValue("DatePromised", Timestamp.class, header, line);
|
|
||||||
String TypeMRP = getValue("TypeMRP", String.class, header, line);
|
|
||||||
String DocStatus = getValue("DocStatus", String.class, header, line);
|
|
||||||
BigDecimal Qty = getValue("Qty", BigDecimal.class, header, line);
|
|
||||||
String MRP_Notice = getValue("MRP_Notice", String.class, header, line);
|
|
||||||
//
|
|
||||||
if (MRP_Notice != null && MRP_Notice.trim().length() > 0)
|
|
||||||
{
|
|
||||||
mrpTest.expectedNotices.add(new MRPNotice(MRP_Notice));
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (TypeMRP == null || TypeMRP.trim().length() == 0)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
I_PP_MRP mrp = MRPTest.createMRP(mrpTest.planning, TypeMRP, DocStatus, Qty, DatePromised);
|
|
||||||
mrp.setDescription("CSV Line "+reader.getLineNumber());
|
|
||||||
if (isGenerated)
|
|
||||||
{
|
|
||||||
mrpTest.expectedMRP.add(mrp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mrpTest.initialMRP.add(mrp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
|
||||||
* Copyright (C) 2008 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.mrp;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
import org.compiere.model.MProduct;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MRP Notice Value Object
|
|
||||||
* @author Teo Sarca, www.arhipac.ro
|
|
||||||
*/
|
|
||||||
public class MRPNotice
|
|
||||||
{
|
|
||||||
public String code;
|
|
||||||
public int AD_Org_ID;
|
|
||||||
public int PP_MRP_ID;
|
|
||||||
public MProduct product;
|
|
||||||
public String documentNo;
|
|
||||||
public BigDecimal qty;
|
|
||||||
public String comment;
|
|
||||||
|
|
||||||
public MRPNotice(String code)
|
|
||||||
{
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return this.code + "["
|
|
||||||
+"AD_Org_ID="+this.AD_Org_ID
|
|
||||||
+", PP_MRP_ID="+this.PP_MRP_ID
|
|
||||||
+", Product="+(this.product != null ? this.product.getValue() : "null")
|
|
||||||
+", DocumentNo="+this.documentNo
|
|
||||||
+", Qty="+this.qty
|
|
||||||
+", Comment="+this.comment
|
|
||||||
+"]";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
|
||||||
* Copyright (C) 2008 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.mrp;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.compiere.model.MProduct;
|
|
||||||
import org.compiere.model.MResource;
|
|
||||||
import org.compiere.model.MWarehouse;
|
|
||||||
import org.compiere.util.Env;
|
|
||||||
import org.eevolution.model.I_PP_MRP;
|
|
||||||
import org.eevolution.model.I_PP_Product_Planning;
|
|
||||||
import org.eevolution.model.MPPMRP;
|
|
||||||
import org.eevolution.model.MPPProductPlanning;
|
|
||||||
|
|
||||||
import test.AdempiereTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MRP Engine Test Case
|
|
||||||
* @author Teo Sarca, www.arhipac.ro
|
|
||||||
*/
|
|
||||||
public class MRPTest extends AdempiereTestCase
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception
|
|
||||||
{
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void test01() throws Exception
|
|
||||||
{
|
|
||||||
// InputStream in = new FileInputStream("D:\\Kituri\\fm");
|
|
||||||
InputStream in = getClass().getClassLoader().getResourceAsStream("test/functional/mrp/MRPTests.csv");
|
|
||||||
CSVFactory factory = new CSVFactory();
|
|
||||||
Collection<TestableMRP> tests = factory.read(in);
|
|
||||||
//
|
|
||||||
for (TestableMRP test : tests)
|
|
||||||
{
|
|
||||||
_testMRP(test);
|
|
||||||
rollback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void _testMRP(TestableMRP test) throws Exception
|
|
||||||
{
|
|
||||||
boolean ok = false;
|
|
||||||
test.trxName = getTrxName();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
test.doIt();
|
|
||||||
// test.dumpStatus();
|
|
||||||
//
|
|
||||||
assertEquals(test.name+": MRP Records# not match", test.expectedMRP.size(), test.actualMRP.size());
|
|
||||||
for (int i = 0; i < test.expectedMRP.size(); i++)
|
|
||||||
{
|
|
||||||
assertEquals(test.name+": MRP Record not match",
|
|
||||||
test.expectedMRP.get(i),
|
|
||||||
test.actualMRP.get(i));
|
|
||||||
}
|
|
||||||
//
|
|
||||||
assertEquals(test.name+": MRP Notices# not match", test.expectedNotices.size(), test.actualNotices.size());
|
|
||||||
for (int i = 0; i < test.expectedNotices.size(); i++)
|
|
||||||
{
|
|
||||||
assertEquals(test.name+": MRP Record not match",
|
|
||||||
test.expectedNotices.get(i).code,
|
|
||||||
test.actualNotices.get(i).code);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
System.err.println("ERRROR_______________________________________");
|
|
||||||
test.dumpStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper Method : Create Product Planning
|
|
||||||
*/
|
|
||||||
public static I_PP_Product_Planning getPlanning(String productValue,
|
|
||||||
String Order_Policy,
|
|
||||||
int Order_Min, int Order_Max, int Order_Pack, int SafetyStock,
|
|
||||||
int Order_Period,
|
|
||||||
int LeadTime)
|
|
||||||
{
|
|
||||||
boolean isPurchased = true;
|
|
||||||
int PlanningHorizon = 365;
|
|
||||||
//
|
|
||||||
Properties ctx = Env.getCtx();
|
|
||||||
// int AD_Client_ID = Env.getAD_Client_ID(ctx);
|
|
||||||
int AD_Org_ID = MRPUtil.getFirst_Org_ID();
|
|
||||||
MWarehouse wh = MRPUtil.getCreateWarehouse(AD_Org_ID, productValue);
|
|
||||||
MResource plant = MRPUtil.getCreatePlant(productValue, wh.get_ID(), PlanningHorizon);
|
|
||||||
MProduct product = getCreateProduct(ctx, productValue, isPurchased);
|
|
||||||
//
|
|
||||||
MPPProductPlanning pp = new MPPProductPlanning(ctx, 0, null);
|
|
||||||
pp.setIsCreatePlan(true);
|
|
||||||
pp.setIsRequiredMRP(true);
|
|
||||||
pp.setIsRequiredDRP(false);
|
|
||||||
pp.setM_Product_ID(product.get_ID());
|
|
||||||
pp.setAD_Org_ID(AD_Org_ID);
|
|
||||||
pp.setM_Warehouse_ID(wh.get_ID());
|
|
||||||
pp.setS_Resource_ID(plant.get_ID());
|
|
||||||
//
|
|
||||||
pp.setOrder_Policy(Order_Policy);
|
|
||||||
pp.setOrder_Min(BigDecimal.valueOf(Order_Min));
|
|
||||||
pp.setOrder_Max(BigDecimal.valueOf(Order_Max));
|
|
||||||
pp.setOrder_Pack(BigDecimal.valueOf(Order_Pack));
|
|
||||||
pp.setSafetyStock(BigDecimal.valueOf(SafetyStock));
|
|
||||||
pp.setOrder_Period(BigDecimal.valueOf(Order_Period));
|
|
||||||
pp.setDeliveryTime_Promised(BigDecimal.valueOf(LeadTime));
|
|
||||||
//
|
|
||||||
return pp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static I_PP_MRP createMRP(I_PP_Product_Planning planning,
|
|
||||||
String TypeMRP, String DocStatus, BigDecimal Qty, Timestamp DatePromised)
|
|
||||||
{
|
|
||||||
Properties ctx = Env.getCtx();
|
|
||||||
//
|
|
||||||
MPPMRP mrp = new MPPMRP(ctx, 0, null);
|
|
||||||
mrp.setAD_Org_ID(planning.getAD_Org_ID());
|
|
||||||
mrp.setName("MRP");
|
|
||||||
mrp.setTypeMRP(TypeMRP);
|
|
||||||
mrp.setDocStatus(DocStatus);
|
|
||||||
mrp.setQty(Qty);
|
|
||||||
mrp.setDatePromised(DatePromised);
|
|
||||||
mrp.setDateStartSchedule(DatePromised);
|
|
||||||
mrp.setDateFinishSchedule(DatePromised);
|
|
||||||
mrp.setDateOrdered(DatePromised);
|
|
||||||
mrp.setM_Product_ID(planning.getM_Product_ID());
|
|
||||||
mrp.setM_Warehouse_ID(planning.getM_Warehouse_ID());
|
|
||||||
return mrp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper Method : Create Product
|
|
||||||
*/
|
|
||||||
public static MProduct getCreateProduct(Properties ctx, String value, boolean isPurchased)
|
|
||||||
{
|
|
||||||
MProduct[] arr = MProduct.get(ctx, "Value='"+value+"'", null);
|
|
||||||
if (arr.length > 0)
|
|
||||||
{
|
|
||||||
return arr[0];
|
|
||||||
}
|
|
||||||
MProduct p = new MProduct(ctx, 0, null);
|
|
||||||
p.setValue(value);
|
|
||||||
p.setName(value);
|
|
||||||
p.setAD_Org_ID(0);
|
|
||||||
p.setProductType (MProduct.PRODUCTTYPE_Item); // I
|
|
||||||
p.setIsBOM (false); // N
|
|
||||||
p.setIsInvoicePrintDetails (false);
|
|
||||||
p.setIsPickListPrintDetails (false);
|
|
||||||
p.setIsPurchased (isPurchased);
|
|
||||||
p.setIsSold (true); // Y
|
|
||||||
p.setIsStocked (true); // Y
|
|
||||||
p.setIsSummary (false);
|
|
||||||
p.setIsVerified (false); // N
|
|
||||||
p.setIsWebStoreFeatured (false);
|
|
||||||
p.setIsSelfService(true);
|
|
||||||
p.setIsExcludeAutoDelivery(false);
|
|
||||||
p.setProcessing (false); // N
|
|
||||||
p.setC_UOM_ID(100); // Each
|
|
||||||
p.saveEx();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertEquals(String message, I_PP_MRP expected, I_PP_MRP actual) throws Exception
|
|
||||||
{
|
|
||||||
boolean equals = expected.getAD_Client_ID() == actual.getAD_Client_ID()
|
|
||||||
&& expected.getAD_Org_ID() == actual.getAD_Org_ID()
|
|
||||||
&& expected.getM_Warehouse_ID() == actual.getM_Warehouse_ID()
|
|
||||||
&& expected.getM_Product_ID() == actual.getM_Product_ID()
|
|
||||||
&& expected.getQty().equals(actual.getQty())
|
|
||||||
&& expected.getTypeMRP().equals(actual.getTypeMRP())
|
|
||||||
&& expected.getDocStatus().equals(actual.getDocStatus())
|
|
||||||
&& expected.getDatePromised().equals(actual.getDatePromised())
|
|
||||||
&& expected.getDateStartSchedule().equals(actual.getDateStartSchedule())
|
|
||||||
&& expected.getDateFinishSchedule().equals(actual.getDateFinishSchedule())
|
|
||||||
&& expected.getDateOrdered().equals(actual.getDateOrdered());
|
|
||||||
//
|
|
||||||
StringBuffer sb = new StringBuffer(message)
|
|
||||||
.append(": expected="+expected)
|
|
||||||
.append(", actual="+actual);
|
|
||||||
|
|
||||||
assertTrue(sb.toString(), equals);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
Generated,DatePromised,TypeMRP,DocStatus,Qty,MRP_Notice,QtyOnHand,LeadTime,Order_Policy,Order_Min,Order_Pack,Today,Order_Max,SafetyStock
|
|
||||||
N,,,,,,4,3,LFL,0,0,30.01.2009,,
|
|
||||||
N,28.02.2009,D,CO,10,,,,,,,30.01.2009,,
|
|
||||||
Y,28.02.2009,S,DR,6,,,,,,,30.01.2009,,
|
|
||||||
|
|
||||||
N,,,,,,0,0,LFL,,,29.01.2009,,
|
|
||||||
N,01.02.2009,D,CO,21,,,,,,,29.01.2009,,
|
|
||||||
Y,01.02.2009,S,DR,21,,,,,0,0,29.01.2009,0,0
|
|
||||||
|
|
||||||
N,,,,,,0,0,LFL,,,29.01.2009,,
|
|
||||||
N,06.02.2009,D,CO,10,,,,,,,29.01.2009,,
|
|
||||||
Y,06.02.2009,S,DR,10,,,,,0,0,29.01.2009,0,0
|
|
||||||
|
|
||||||
N,,,,,,0,0,LFL,15,,29.01.2009,,
|
|
||||||
N,06.02.2009,D,CO,10,MRP-080,,,,,,29.01.2009,,
|
|
||||||
Y,06.02.2009,S,DR,15,,,,,,,29.01.2009,,
|
|
|
|
@ -1,22 +0,0 @@
|
||||||
MRPTests Format/Rules:
|
|
||||||
|
|
||||||
* Tests are separated by a completelly empty line
|
|
||||||
* First line from each test is containing the product data planning parameters;
|
|
||||||
The CSV column names are identical with those from PP_Product_Planning table.
|
|
||||||
* Next lines are the MRP records; The CSV column names are identical with those from PP_MRP table.
|
|
||||||
* The "Generated" column (first column from CSV file) is applicable just for MRP record lines and means:
|
|
||||||
N = This record is not generated and it will be created before running the MRP engine.
|
|
||||||
Y = This record IS generated. We expect this as a resulting MRP record after MRP engine runs.
|
|
||||||
* The "MRP_Notice" column specify that we expect that MRP notice to be throwed by MRP engine.
|
|
||||||
For more informations regarding MRP notices please run following SQL query:
|
|
||||||
SELECT Value, MsgText, MsgTip FROM AD_Message WHERE value LIKE 'MRP-%'
|
|
||||||
ORDER BY Value
|
|
||||||
* The "Today" column specify which is the "Today" date for MRP engine. In a normal environment (i.e. running Adempiere client),
|
|
||||||
MRP engine assumes that Today is system date
|
|
||||||
* The "LeadTime" column is PP_ProductPlanning.DeliveryTime_Promised
|
|
||||||
|
|
||||||
|
|
||||||
For any other questions, please ask in ADempiere forums ;)
|
|
||||||
|
|
||||||
Best regards,
|
|
||||||
Teo Sarca - www.arhipac.ro
|
|
|
@ -1,109 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
|
||||||
* Copyright (C) 2008 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.mrp;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.compiere.model.MLocation;
|
|
||||||
import org.compiere.model.MResource;
|
|
||||||
import org.compiere.model.MWarehouse;
|
|
||||||
import org.compiere.model.Query;
|
|
||||||
import org.compiere.util.DB;
|
|
||||||
import org.compiere.util.Env;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Many helper methods for producing different entities
|
|
||||||
* @author Teo Sarca, www.arhipac.ro
|
|
||||||
*/
|
|
||||||
public class MRPUtil
|
|
||||||
{
|
|
||||||
|
|
||||||
public static int getFirst_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)
|
|
||||||
{
|
|
||||||
Properties ctx = Env.getCtx();
|
|
||||||
int AD_Client_ID = Env.getAD_Client_ID(ctx);
|
|
||||||
String whereClause = "AD_Client_ID=? AND AD_Org_ID=? AND Value=?";
|
|
||||||
MWarehouse wh = new Query(ctx, MWarehouse.Table_Name, whereClause, null)
|
|
||||||
.setParameters(new Object[]{AD_Client_ID, AD_Org_ID, value})
|
|
||||||
.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 Plant (S_Resource_ID)
|
|
||||||
*/
|
|
||||||
public static MResource getCreatePlant(String value, int M_Warehouse_ID, int PlanningHorizon)
|
|
||||||
{
|
|
||||||
Properties ctx = Env.getCtx();
|
|
||||||
int AD_Client_ID = Env.getAD_Client_ID(ctx);
|
|
||||||
String whereClause = MResource.COLUMNNAME_Value+"=? AND AD_Client_ID=?";
|
|
||||||
MResource r = new Query(ctx, MResource.Table_Name, whereClause, null)
|
|
||||||
.setParameters(new Object[]{value, AD_Client_ID})
|
|
||||||
.firstOnly();
|
|
||||||
if (r == null)
|
|
||||||
{
|
|
||||||
r = new MResource(ctx, 0, null);
|
|
||||||
int S_ResourceType_ID = DB.getSQLValueEx(null,
|
|
||||||
"SELECT MIN(S_ResourceType_ID) FROM S_Resource WHERE AD_Client_ID=? AND IsAvailable=?",
|
|
||||||
AD_Client_ID, true);
|
|
||||||
r.setS_ResourceType_ID(S_ResourceType_ID);
|
|
||||||
}
|
|
||||||
r.setValue(value);
|
|
||||||
r.setName(value);
|
|
||||||
r.setIsManufacturingResource(true);
|
|
||||||
r.setManufacturingResourceType(MResource.MANUFACTURINGRESOURCETYPE_Plant);
|
|
||||||
r.setIsAvailable(true);
|
|
||||||
r.setM_Warehouse_ID(M_Warehouse_ID);
|
|
||||||
r.setPlanningHorizon(PlanningHorizon);
|
|
||||||
r.setPercentUtilization(Env.ONEHUNDRED);
|
|
||||||
r.saveEx();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(Object[] arr)
|
|
||||||
{
|
|
||||||
if (arr == null)
|
|
||||||
return "null";
|
|
||||||
//
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
int i = 1;
|
|
||||||
sb.append("(size="+arr.length+")");
|
|
||||||
for (Object o : arr)
|
|
||||||
{
|
|
||||||
sb.append("["+i+":"+o+"]");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
|
||||||
* Copyright (C) 2008 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.mrp;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.compiere.model.MProduct;
|
|
||||||
import org.compiere.model.PO;
|
|
||||||
import org.compiere.util.DB;
|
|
||||||
import org.compiere.util.Env;
|
|
||||||
import org.eevolution.model.I_PP_MRP;
|
|
||||||
import org.eevolution.model.I_PP_Product_Planning;
|
|
||||||
import org.eevolution.model.X_PP_MRP;
|
|
||||||
import org.eevolution.process.MRP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extends {@link MRP} engine process and simulates initial context
|
|
||||||
* (product data planning, existing MRP records).
|
|
||||||
*
|
|
||||||
* @author Teo Sarca, www.arhipac.ro
|
|
||||||
*/
|
|
||||||
class TestableMRP extends org.eevolution.process.MRP
|
|
||||||
{
|
|
||||||
public String name = "junit-test";
|
|
||||||
public String description = "";
|
|
||||||
public String trxName = null;
|
|
||||||
public String productValue = "junit-test";
|
|
||||||
public I_PP_Product_Planning planning;
|
|
||||||
public Timestamp today;
|
|
||||||
public BigDecimal qtyOnHand;
|
|
||||||
//
|
|
||||||
public List<I_PP_MRP> initialMRP = new ArrayList<I_PP_MRP>();
|
|
||||||
public List<I_PP_MRP> expectedMRP = new ArrayList<I_PP_MRP>();
|
|
||||||
public List<I_PP_MRP> actualMRP = new ArrayList<I_PP_MRP>();
|
|
||||||
//
|
|
||||||
public List<MRPNotice> expectedNotices = new ArrayList<MRPNotice>();
|
|
||||||
public List<MRPNotice> actualNotices = new ArrayList<MRPNotice>();
|
|
||||||
|
|
||||||
public TestableMRP()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Properties getCtx()
|
|
||||||
{
|
|
||||||
return Env.getCtx();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected String get_TrxName()
|
|
||||||
{
|
|
||||||
return this.trxName;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected int getAD_Client_ID()
|
|
||||||
{
|
|
||||||
return this.planning.getAD_Client_ID();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int getAD_Org_ID()
|
|
||||||
{
|
|
||||||
return this.planning.getAD_Org_ID();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int getM_Warehouse_ID()
|
|
||||||
{
|
|
||||||
return this.planning.getM_Warehouse_ID();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int getPlant_ID()
|
|
||||||
{
|
|
||||||
return this.planning.getS_Resource_ID();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean isRequiredDRP()
|
|
||||||
{
|
|
||||||
return this.planning.isRequiredDRP();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected I_PP_Product_Planning getProductPlanning(int AD_Client_ID, int AD_Org_ID,
|
|
||||||
int S_Resource_ID, int M_Warehouse_ID, MProduct product)
|
|
||||||
{
|
|
||||||
return this.planning;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected BigDecimal getQtyOnHand(I_PP_Product_Planning pp)
|
|
||||||
{
|
|
||||||
return this.qtyOnHand;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected Timestamp getToday()
|
|
||||||
{
|
|
||||||
return this.today;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void createMRPNote(String code, int AD_Org_ID, int PP_MRP_ID, MProduct product, String documentNo, BigDecimal qty, String comment)
|
|
||||||
{
|
|
||||||
MRPNotice note = new MRPNotice(code);
|
|
||||||
note.AD_Org_ID = AD_Org_ID;
|
|
||||||
note.PP_MRP_ID = PP_MRP_ID;
|
|
||||||
note.product = product;
|
|
||||||
note.documentNo = documentNo;
|
|
||||||
note.qty = qty;
|
|
||||||
note.comment = comment;
|
|
||||||
this.actualNotices.add(note);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void createDDOrder(int AD_Org_ID, int PP_MRP_ID, MProduct product, BigDecimal QtyPlanned, Timestamp DemandDateStartSchedule)
|
|
||||||
{
|
|
||||||
createMRPSupply(AD_Org_ID, PP_MRP_ID, product, QtyPlanned, DemandDateStartSchedule);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void createPPOrder(int AD_Org_ID, int PP_MRP_ID, MProduct product, BigDecimal QtyPlanned, Timestamp DemandDateStartSchedule)
|
|
||||||
{
|
|
||||||
createMRPSupply(AD_Org_ID, PP_MRP_ID, product, QtyPlanned, DemandDateStartSchedule);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void createRequisition(int AD_Org_ID, int PP_MRP_ID, MProduct product, BigDecimal QtyPlanned, Timestamp DemandDateStartSchedule)
|
|
||||||
{
|
|
||||||
createMRPSupply(AD_Org_ID, PP_MRP_ID, product, QtyPlanned, DemandDateStartSchedule);
|
|
||||||
}
|
|
||||||
private void createMRPSupply(int AD_Org_ID, int PP_MRP_ID, MProduct product, BigDecimal QtyPlanned, Timestamp DemandDateStartSchedule)
|
|
||||||
{
|
|
||||||
I_PP_MRP mrp = MRPTest.createMRP(this.planning, X_PP_MRP.TYPEMRP_Supply, X_PP_MRP.DOCSTATUS_Drafted,
|
|
||||||
QtyPlanned, DemandDateStartSchedule);
|
|
||||||
((PO)mrp).saveEx(get_TrxName());
|
|
||||||
this.actualMRP.add(mrp);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String doIt() throws Exception
|
|
||||||
{
|
|
||||||
this.p_M_Product_ID = this.planning.getM_Product_ID();
|
|
||||||
// Create MRP lines:
|
|
||||||
for (I_PP_MRP mrp : this.initialMRP)
|
|
||||||
((PO)mrp).saveEx(get_TrxName());
|
|
||||||
//
|
|
||||||
return super.doIt();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void deleteMRP(int AD_Client_ID, int AD_Org_ID, int S_Resource_ID, int M_Warehouse_ID)
|
|
||||||
{
|
|
||||||
// Delete all MRP records for our testing product
|
|
||||||
String sql = "DELETE FROM PP_MRP"
|
|
||||||
+" WHERE AD_Client_ID=? AND AD_Org_ID=?"
|
|
||||||
+" AND M_Warehouse_ID=? AND S_Resource_ID=?"
|
|
||||||
+" AND M_Product_ID=?";
|
|
||||||
int no = DB.executeUpdateEx(sql,
|
|
||||||
new Object[]{AD_Client_ID, AD_Org_ID,
|
|
||||||
M_Warehouse_ID, S_Resource_ID, this.p_M_Product_ID},
|
|
||||||
get_TrxName());
|
|
||||||
log.info("[DEBUG] clean up MRP #"+no);
|
|
||||||
//
|
|
||||||
super.deleteMRP(AD_Client_ID, AD_Org_ID, S_Resource_ID, M_Warehouse_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dumpStatus()
|
|
||||||
{
|
|
||||||
log.info("------------ MRP TEST --------------");
|
|
||||||
log.info(" Name : "+this.name);
|
|
||||||
log.info(" Description : "+this.description);
|
|
||||||
log.info(" Product : "+this.productValue);
|
|
||||||
log.info(" Today : "+this.today);
|
|
||||||
log.info(" QtyOnHand : "+this.qtyOnHand);
|
|
||||||
((PO)this.planning).dump();
|
|
||||||
//
|
|
||||||
log.info("------------ Initial MRP --------------");
|
|
||||||
for (I_PP_MRP mrp : this.initialMRP)
|
|
||||||
log.info(" "+((PO)mrp).toString());
|
|
||||||
log.info("------------ Expected MRP --------------");
|
|
||||||
for (I_PP_MRP mrp : this.expectedMRP)
|
|
||||||
log.info(" "+((PO)mrp).toString());
|
|
||||||
log.info("------------ Actual MRP --------------");
|
|
||||||
for (I_PP_MRP mrp : this.actualMRP)
|
|
||||||
log.info((" "+(PO)mrp).toString());
|
|
||||||
log.info("------------ Expected NOTICES --------------");
|
|
||||||
for (MRPNotice notice : this.expectedNotices)
|
|
||||||
log.info(" "+notice.toString());
|
|
||||||
log.info("------------ Actual NOTICES --------------");
|
|
||||||
for (MRPNotice notice : this.actualNotices)
|
|
||||||
log.info(" "+notice.toString());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue