Code Scratchpad: Java: iDempiere API

From iDempiere en
Jump to navigation Jump to search


The purpose of this page is to share commonly used iDempiere API calls.

Feel free to contribute here to improve the coverage of documentation.

Get the client ID

Env.getContextAsInt(ctx, "#AD_Client_ID")

Get the base currency

MClient.get(Env.getCtx()).getC_Currency_ID()

Get the process ID for process with key

int AD_Process_ID = MProcess.getProcess_ID("KeyValueOfProcess", null);

Start a report & process

ProcessUtil.startJavaProcess(ctx, poInfo, trx);

  • See FinReportJasper in the base code for example

Commit transaction

Trx trx = Trx.get(get_TrxName(), false);
trx.commit(true);

Complete document

String docAction = DocAction.ACTION_Complete;
		posOrder.setDocAction( docAction );
		posOrder.processIt( docAction );
		posOrder.saveEx();
  • NB: Check the document status after saving is equal to the expected status, otherwise an exception should be thrown.

Get the persistent object

Standard

MBPartner partner = new MBPartner(getCtx(), {0 for new record, or record id}, get_TrxName());

Model factory

The following is work in progress

  • Using model factory, so that the correct model is returned, based on the available plugins.
    • MTable.getPO (write a utility method to wrap)
    • Use a Query (see the Query class)
    • Write a utility method based on MTable.getPO, which doesn't require instantiating MTable
public PO getPO (int Record_ID, String trxName)
	{
		String tableName = getTableName();
		if (Record_ID != 0 && !isSingleKey())
		{
			log.log(Level.WARNING, "(id) - Multi-Key " + tableName);
			return null;
		}

		PO po = null;
		List<IModelFactory> factoryList = Service.locator().list(IModelFactory.class).getServices();
		if (factoryList != null)
		{
			for(IModelFactory factory : factoryList)
			{
				po = factory.getPO(tableName, Record_ID, trxName);
				if (po != null)
				{
					if (po.get_ID() != Record_ID && Record_ID > 0)
						po = null;
					else
						break;
				}
			}
		}

		if (po == null)
		{
			po = new GenericPO(tableName, getCtx(), Record_ID, trxName);
			if (po.get_ID() != Record_ID && Record_ID > 0)
				po = null;
		}

		return po;
	}	//	getPO

Reset the cache for a table

CacheMgt.get().reset(Table_Name);

Lock PO for update

see AdempiereDatabase.forUpdate:

public boolean forUpdate(PO po, int timeout);

Attachments

Attach one or more files to a record

  • Example copied from the PIPO code:
MAttachment attachment = new MAttachment (adPackageImp.getCtx(), X_AD_Package_Imp_Proc.Table_ID, adPackageImp.getAD_Package_Imp_Proc_ID(), null);
attachment.addEntry(packageFile);
attachment.saveEx(); 

System configurator

MSysConfig.getBooleanValue("CONFIG_NAME", true)

String retValue = MSysConfig.getValue("CONFIG_NAME", "");

Creating an order line

  • Similiar logic applies to an invoice line.
MOrderLine line = new MOrderLine(order);
line.setC_BPartner_ID(C_BPartner_ID);
line.setM_Product_ID(M_Product_ID);
line.setQty(BigDecimal.ONE);
// Sets the price based on the price list
line.setPrice();
// Extends the qty
line.setLineNetAmt();
line.saveEx();

Methods for querying and updating data

Query API

  • Example taken from ModelValidationEngine
MTable table = MTable.get(Env.getCtx(), X_AD_ModelValidator.Table_ID);
Query query = table.createQuery("IsActive='Y'", null);
query.setOrderBy("SeqNo");
..
List<X_AD_ModelValidator> entityTypes = query.list();
..
List<MInfoWindow> list = new Query(Env.getCtx(),
MInfoWindow.Table_Name, "IsValid='Y' AND
IsShowInDashboard='Y'", null)
        .setOnlyActiveRecords(true)
        .setOrderBy(MInfoWindow.COLUMNNAME_SeqNo)
        .list();

Prepared Statement

final String sql = "SELECT * FROM C_BPartner_Location WHERE C_BPartner_ID=? AND IsActive='Y'"
				+ " ORDER BY C_BPartner_Location_ID";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
	pstmt = DB.prepareStatement(sql, get_TrxName());
	pstmt.setInt(1, getC_BPartner_ID());
	rs = pstmt.executeQuery();
	while (rs.next())
		list.add(new MBPartnerLocation (getCtx(), rs, get_TrxName()));
}
catch (Exception e)
{
	log.log(Level.SEVERE, sql, e);
}
finally
{
	DB.close(rs, pstmt);
	rs = null; pstmt = null;
}

Get all IDs

int[] m_ids = PO.getAllIDs(MAttachment.Table_Name, " AD_Client_ID= " + MClient.get(getCtx()).getAD_Client_ID() + " Order By AD_Client_ID ", null);

DB.getSQLValue

StringBuilder sql = new StringBuilder();
sql.append("select count(*) from TableName where TableName_ID=").append(TableName_ID));

return DB.getSQLValueEx(trxName sql, params);

Update

DB.executeUpdateEx(sql.toString(), new Object[] { ... }, trxName);

Access control related

Window access

  • Check whether currently logged in role has access to window
  • @return null if no access, TRUE if r/w and FALSE if r/o
if (MRole.getDefault().getWindowAccess(m_AD_Window_ID) == null) { ... }

UI related

Busy Dialog

* BusyDialogTemplate: A busy dialog with an encapsulated Runnable

Translations

Simple get message text

Msg.getMsg(Env.getCtx(), "messagekey")

Translation of column (element)

String columnNameTrl = Msg.getElement(Env.getCtx(), columnName);

Pack Out

Add support to export new or existing display type

PoExporter.export

User preferences

  • Untested, use at your own risk
  • You can use the context for settings that don't need to be persisted.
protected void savePreferences() {
		String note = txtNote.getText();
		UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
		pref.setProperty(getPrefKeyForNote(), note);
		pref.savePreference();
	}
	
	protected void loadPreferences() {
		UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
		String note = pref.getProperty(getPrefKeyForNote());
		if (note==null) {
			return;
		}
		txtNote.setText(note);
	}

Context

Adding a new context variable just after login

  • See: Login.loadPreferences

Logging

  • For everything you need to know about logging in iDempiere, see the CLogMgt class

MD5, hashes, checksums, archives

Compare MD5's and more

DigestOfFile

Create zip archives

Zipper

Code paths

User clicks on New record

1) When user click on New Record button in any window, onNew() function in AbstractADWindowContent class is executed. Please check AbstractADWindowContent class for other functions (onSave,onProcess,onReport etc) as well.

2) getCurrentNext() and setCurrentNext() in MSequence class. Thank you very much Anozi Mada

Regards, Shanil Fernando

Reference: https://groups.google.com/forum/#!topic/idempiere/aSsv1MkciwM

Toolbar delete button

  • Where do I find the code which handles deletion of a record from the toolbar?
AbstractADWindowContent.onDeleteCallback

Toolbar refresh button

AbstractADWindowContent.onRefresh

Toolbar export button

AbstractADWindowContent.onExport

  • See: ExportAction

Toolbar import button

AbstractADWindowContent.onFileImport --> FileImportAction.fileImport --> importFile --> GridTabCSVImporter.fileImport

Process Dialog

Dialog to start process or report

ProcessDialog

Process Info Dialog

  • The dialog shown after a user starts a process from a window
ProcessInfoDialog
  • Shown from:
AbstractADWindowContent.updateUI

User starts process by clicking on a button on a window

AbstractADWindowContent.actionButton

Clicking on a menu item

Where do I find the code which responds to an item being clicked on the menu?

AbstractDesktop.onMenuSelected

Opening of a window

  • Where is the opening of a window handled?
    • Same class for form, process, workflow, info
TabbedDesktop.openWindow

Display and layout of fields

  • Where do I find the logic which handles the display and layout of fields in a standard iDempiere window?
ADTabpanel
  • Where is formatting is applied to fields (example, required fields highlighted in red)?
WEditor.applyLabelStyles
  • Where do I find the container for a field which is displayed in a window?
    • Also handles setting the default value for a field
GridField
  • Where are callouts processed?
GridTab.processCallout
  • Where is the field change event for when a value changes on a window?
GridTab.processFieldChange

Printing

  • Handle printing for various documents
ServerReportCtl

Application startups

Model Generator

ModelGeneratorApplication ->  ModelClassGeneratorDialog -> ModelClassGenerator 

This page is brought to you by nTier Software Services. Feel free to improve directly or suggest using the Discussion tab.