PowerPoint presentation from an Austin JUG (java user's group) event in June. The purpose of the presentation is to help Java developers learn, use and extent ADemipere, a popular open source ERP.
Introduction to
Open Source ERP
for Java Developers
(Compiere, ADempiere and Openbravo)
Presented by:
Chuck Boecking from Trek Global
512.850.6068
Note: If you find this presentation helpful or if you have recommendations, please
reach out and let me know. Thanks!
Why a Java Developer Should Care
● Open Source ERP is approaching the tipping
point of business acceptance.
● This tipping point gives the Java developers
more freedom and flexibility when adopting
platforms to solve wide-scale business
problems.
● A single company-wide open source system
gives developers more resources to drive
and change business.
Interesting Points
● Compiere, ADempiere and OpenBravo are
mature and stable solutions for managing
goods and services in enterprises from
$50M to $500M in gross revenue.
● Discussion topics will include architecture,
application, performance tuning and war
stories.
What is ERP?
ERP or Enterprise Resource Planning is a
single application that brings many common
organizational features into a single package.
Features include:
Accounting (GL, AP, AR) Inventory Management CRM (Customer Management
Receiving Purchasing (Order) Fulfillment and Shipping
Management
Product Management Sales (Order) Management Manufacturing
Customer Management Vendor Management Service Management
Case Studies Worth Reading
Complex inspection and wholesale distribution
● 120 users across many countries and
multiple financial entities
● Why notable: extensive customization
High volume wholesale and retail distribution
● 300 concurrent users shipping 10M units per
month across 140K order lines
● Why notable: high volume
Technology Stack
● Java SE
● Tomcat and JBoss
● Model Driven Architecture - application
dictionary
● zk WebUI and Java Swing
● PostgreSQL DB and Oracle DB
● 2Pack Release Management
Notable: supports end-to-end license-free
usage for companies with up to 500 concurrent
users.
ADempiere Statistics
● Just under 3000 classes w/o including auto-
generated model classes
● About 800 tables
● Created in sf.net in 2006 as a fork from
Compiere
● Historically one of sf.net's most active
projects
Common Developer Entry Points
Developer hooks for implementing logic and
automation:
● Callout - based on user interactions with UI.
● Model - based on interaction with
persistence layer.
● Processes - based on users deliberately
pressing a button or invoking a menu action.
Other: Context - helps control visibility and
default values and is also accessible from code
almost anywhere.
Callout
package org.adempiere.callout;
import java.util.Properties;
import org.compiere.model.CalloutEngine;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.util.AdempiereSystemError;
import org.compiere.util.Env;
public class SimpleCallout extends CalloutEngine {
public String test(Properties ctx, int windowNo, GridTab mTab, GridField mField,
Object value) throws AdempiereSystemError {
// First get value
Price = ((BigDecimal)mTab.getValue("Price"));
// do some calculations
BigDecimal Total = Qty.multiply(Price);
// Set value back to column field
mTab.setValue("Total", Total);
return "this is a return string";
}
}
Source: http://www.adempiere.com/Callout
Model
package adempiere.model;
import org.compiere.model.X_XX_Material;
public class MMaterial extends X_XX_Material {
/** Create & Load existing Persistent Object */
public MMaterial(Properties ctx, int XX_Material_ID, String trxName) {
super(ctx, XX_Material_ID, trxName);
// other initializations here
}
/** Create & Load existing Persistent Object. */
public MMaterial(Properties ctx, ResultSet rs, String trxName) {
super(ctx, rs, trxName);
// other initializations here
}
/** [OPTIONAL] Called before Save for Pre-Save Operation. */
protected boolean beforeSave(boolean newRecord)
{
return true;
}
/** ... afterSave(), getters, setters, convenience methods */
}
Example: http://www.adempiere.com/NewWindow
Process
package org.compiere.process;
public class TemplateProcess extends SvrProcess {
private PO record;
@Override
protected void prepare() {
for ( ProcessInfoParameter para : getParameter())
{ ...handle parameters...
}
// you can also retrieve the id of the current record for processes called from a window
int recordId = getRecord_ID();
}
@Override
protected String doIt() throws Exception {
/* Commonly the doIt method firstly do some validations on the parameters
and throws AdempiereUserException or AdempiereSystemException if errors found */
return "A message to the user (indicating success - failures must throw Exceptions)";
}
/** Post process actions (outside trx). */
@Override
protected void postProcess(boolean success) {
if (success) {} else { }
}
}
http://www.adempiere.com/Process
War Stories
Complex: CSI inspection
Volume: 10M units from worldwide distribution
eCommerce: 3 webstores => 1K shipments/day
Project Management: Time tracking
Chuck Boecking
● Started with Compiere in 2003
● Open Source ERP 70 to 90% since 2006
● Professional educator and integrator
● Wholesale distribution and assembly
specialty
Chuck Boecking
512.850.6068
cboecking@trekglobal.com