FR [ 2552432 ] Create JUnit MRP tests

http://sourceforge.net/tracker/index.php?func=detail&aid=2552432&group_id=176962&atid=879335
This commit is contained in:
teo_sarca 2009-01-31 13:33:16 +00:00
parent 3bf2c62644
commit 0b0c6de47e
10 changed files with 869 additions and 13 deletions

View File

@ -142,5 +142,7 @@
<classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/itext-1.3.jar"/> <classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/itext-1.3.jar"/>
<classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/log4j-1.2.13.jar"/> <classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/log4j-1.2.13.jar"/>
<classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/poi-3.0-FINAL.jar"/> <classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/poi-3.0-FINAL.jar"/>
<classpathentry exported="true" kind="lib" path="tools/lib/testing/spiffy-with_source-all-0.05.jar"/>
<classpathentry exported="true" kind="lib" path="tools/lib/testing/SuperCSV-with_src-1.52.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -45,6 +45,14 @@ public interface I_PP_MRP
/** Load Meta Data */ /** Load Meta Data */
/** Column name AD_Client_ID */
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
/** Get Client.
* Client/Tenant for this installation.
*/
public int getAD_Client_ID();
/** Column name AD_Org_ID */ /** Column name AD_Org_ID */
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID"; public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
@ -103,6 +111,22 @@ public interface I_PP_MRP
public I_C_Order getC_Order() throws RuntimeException; public I_C_Order getC_Order() throws RuntimeException;
/** Column name Created */
public static final String COLUMNNAME_Created = "Created";
/** Get Created.
* Date this record was created
*/
public Timestamp getCreated();
/** Column name CreatedBy */
public static final String COLUMNNAME_CreatedBy = "CreatedBy";
/** Get Created By.
* User who created this records
*/
public int getCreatedBy();
/** Column name DD_OrderLine_ID */ /** Column name DD_OrderLine_ID */
public static final String COLUMNNAME_DD_OrderLine_ID = "DD_OrderLine_ID"; public static final String COLUMNNAME_DD_OrderLine_ID = "DD_OrderLine_ID";
@ -222,6 +246,19 @@ public interface I_PP_MRP
*/ */
public String getDocStatus(); public String getDocStatus();
/** Column name IsActive */
public static final String COLUMNNAME_IsActive = "IsActive";
/** Set Active.
* The record is active in the system
*/
public void setIsActive (boolean IsActive);
/** Get Active.
* The record is active in the system
*/
public boolean isActive();
/** Column name IsAvailable */ /** Column name IsAvailable */
public static final String COLUMNNAME_IsAvailable = "IsAvailable"; public static final String COLUMNNAME_IsAvailable = "IsAvailable";
@ -437,6 +474,22 @@ public interface I_PP_MRP
/** Get TypeMRP */ /** Get TypeMRP */
public String getTypeMRP(); public String getTypeMRP();
/** Column name Updated */
public static final String COLUMNNAME_Updated = "Updated";
/** Get Updated.
* Date this record was updated
*/
public Timestamp getUpdated();
/** Column name UpdatedBy */
public static final String COLUMNNAME_UpdatedBy = "UpdatedBy";
/** Get Updated By.
* User who updated this records
*/
public int getUpdatedBy();
/** Column name Value */ /** Column name Value */
public static final String COLUMNNAME_Value = "Value"; public static final String COLUMNNAME_Value = "Value";

View File

@ -36,7 +36,7 @@ public class X_PP_MRP extends PO implements I_PP_MRP, I_Persistent
/** /**
* *
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 20081221L;
/** Standard Constructor */ /** Standard Constructor */
public X_PP_MRP (Properties ctx, int PP_MRP_ID, String trxName) public X_PP_MRP (Properties ctx, int PP_MRP_ID, String trxName)
@ -427,10 +427,7 @@ public class X_PP_MRP extends PO implements I_PP_MRP, I_Persistent
public void setDocStatus (String DocStatus) public void setDocStatus (String DocStatus)
{ {
if (DocStatus == null || DocStatus.equals("DR") || DocStatus.equals("CO") || DocStatus.equals("AP") || DocStatus.equals("NA") || DocStatus.equals("VO") || DocStatus.equals("IN") || DocStatus.equals("RE") || DocStatus.equals("CL") || DocStatus.equals("??") || DocStatus.equals("IP") || DocStatus.equals("WP") || DocStatus.equals("WC")); if (DocStatus == null || DocStatus.equals("DR") || DocStatus.equals("CO") || DocStatus.equals("AP") || DocStatus.equals("NA") || DocStatus.equals("VO") || DocStatus.equals("IN") || DocStatus.equals("RE") || DocStatus.equals("CL") || DocStatus.equals("??") || DocStatus.equals("IP") || DocStatus.equals("WP") || DocStatus.equals("WC")); else throw new IllegalArgumentException ("DocStatus Invalid value - " + DocStatus + " - Reference_ID=131 - DR - CO - AP - NA - VO - IN - RE - CL - ?? - IP - WP - WC"); set_Value (COLUMNNAME_DocStatus, DocStatus);
else throw new IllegalArgumentException ("DocStatus Invalid value - " + DocStatus + " - Reference_ID=131 - DR - CO - AP - NA - VO - IN - RE - CL - ?? - IP - WP - WC");
set_Value (COLUMNNAME_DocStatus, DocStatus);
} }
/** Get Document Status. /** Get Document Status.
@ -742,10 +739,7 @@ public class X_PP_MRP extends PO implements I_PP_MRP, I_Persistent
public void setOrderType (String OrderType) public void setOrderType (String OrderType)
{ {
if (OrderType == null || OrderType.equals("FCT") || OrderType.equals("MOP") || OrderType.equals("POO") || OrderType.equals("POR") || OrderType.equals("SOO") || OrderType.equals("DOO")); if (OrderType == null || OrderType.equals("FCT") || OrderType.equals("MOP") || OrderType.equals("POO") || OrderType.equals("POR") || OrderType.equals("SOO") || OrderType.equals("DOO")); else throw new IllegalArgumentException ("OrderType Invalid value - " + OrderType + " - Reference_ID=53229 - FCT - MOP - POO - POR - SOO - DOO"); set_Value (COLUMNNAME_OrderType, OrderType);
else throw new IllegalArgumentException ("OrderType Invalid value - " + OrderType + " - Reference_ID=53229 - FCT - MOP - POO - POR - SOO - DOO");
set_Value (COLUMNNAME_OrderType, OrderType);
} }
/** Get OrderType. /** Get OrderType.
@ -953,10 +947,7 @@ public class X_PP_MRP extends PO implements I_PP_MRP, I_Persistent
public void setTypeMRP (String TypeMRP) public void setTypeMRP (String TypeMRP)
{ {
if (TypeMRP == null || TypeMRP.equals("D") || TypeMRP.equals("S")); if (TypeMRP == null || TypeMRP.equals("D") || TypeMRP.equals("S")); else throw new IllegalArgumentException ("TypeMRP Invalid value - " + TypeMRP + " - Reference_ID=53230 - D - S"); set_Value (COLUMNNAME_TypeMRP, TypeMRP);
else throw new IllegalArgumentException ("TypeMRP Invalid value - " + TypeMRP + " - Reference_ID=53230 - D - S");
set_Value (COLUMNNAME_TypeMRP, TypeMRP);
} }
/** Get TypeMRP. /** Get TypeMRP.

View File

@ -0,0 +1,211 @@
/******************************************************************************
* 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);
}
}
}

View File

@ -0,0 +1,50 @@
/******************************************************************************
* 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
+"]";
}
}

View File

@ -0,0 +1,207 @@
/******************************************************************************
* 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);
}
}

View File

@ -0,0 +1,16 @@
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 Generated DatePromised TypeMRP DocStatus Qty MRP_Notice QtyOnHand LeadTime Order_Policy Order_Min Order_Pack Today Order_Max SafetyStock
2 N 4 3 LFL 0 0 30.01.2009
3 N 28.02.2009 D CO 10 30.01.2009
4 Y 28.02.2009 S DR 6 30.01.2009
5 N 0 0 LFL 29.01.2009
6 N 01.02.2009 D CO 21 29.01.2009
7 Y 01.02.2009 S DR 21 0 0 29.01.2009 0 0
8 N 0 0 LFL 29.01.2009
9 N 06.02.2009 D CO 10 29.01.2009
10 Y 06.02.2009 S DR 10 0 0 29.01.2009 0 0
11 N 0 0 LFL 15 29.01.2009
12 N 06.02.2009 D CO 10 MRP-080 29.01.2009
13 Y 06.02.2009 S DR 15 29.01.2009

View File

@ -0,0 +1,22 @@
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

View File

@ -0,0 +1,109 @@
/******************************************************************************
* 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();
}
}

View File

@ -0,0 +1,195 @@
/******************************************************************************
* 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());
}
}