Openbravo ERP 3.0 Shortcuts

Hi Folks,

Presented here is the Openbravo ERP 3.0 Shortcuts. For the list of short cuts for Openbravo ERP 2.50 click here .

 

Radio Button Reference for Openbravo

Last month I happened to see this issue, https://forge.openbravo.com/plugins/espforum/view.php?group_id=100&forumid=549512&topicid=7022038 accidentally, and I was more inclined about the solution model. Radio buttons are very common and are quite useful, but its surprising to note that it has not found its place in Openbravo. I felt Radio Button can be used in many places and that it should be part of the standard Reference Types. I could not get more in to it at that time, but couple of days ago got some time out of work and got a chance to give it a shot. I took the Yes/No Reference type as the base and remodelled the html file (WADYesNo.html) alone and then I was able to create a radio buttons out of it. I thought to contribute it to the community as a small dedication to the great work that is being in progress.

Feel free to buzz me at shankar@fugoconsulting.com. I would be glad to help the community and contribute in a small way that I can. I have also been trying to write some blogs about the basic issues that we face in Openbravo ERP. You can look at those at https://fugoconsulting.wordpress.com/category/openbravo/.

Solution Model:

The following are the sequence of files that I changed for the solution. All these are not needed to bring out a basic Radio Button especially  the skin images. But I have provided it as reference to the sequence of files to be added for a new reference type.

In src-wad/src/org/openbravo/wad/controls add the following files:

  • WADRadioButton.java
/*
 @author: Shankar Balachandran
*/
package org.openbravo.wad.controls;

import java.util.Properties;

import org.openbravo.xmlEngine.XmlDocument;

public class WADRadioButton extends WADControl {

 public WADRadioButton() {
 }

 public WADRadioButton(Properties prop) {
 setInfo(prop);
 initialize();
 }

 public void initialize() {
 generateJSCode();
 }

 private void generateJSCode() {
 setValidation("");
 setCalloutJS();
 }

 public String getType() {
 return "Radio_Check";
 }

 public String editMode() {
 XmlDocument xmlDocument = getReportEngine().readXmlTemplate(
 "org/openbravo/wad/controls/WADRadioButton").createXmlDocument();

 xmlDocument.setParameter("columnName", getData("ColumnName"));
 xmlDocument.setParameter("columnNameInp", getData("ColumnNameInp"));

 if (getData("IsReadOnly").equals("Y") || getData("IsReadOnlyTab").equals("Y")
 || getData("IsUpdateable").equals("N")) {
 xmlDocument.setParameter("disabled", "Y");
 xmlDocument.setParameter("logChanges", "");
 xmlDocument.setParameter("disabledFalse", "return false;");
 } else {
 xmlDocument.setParameter("disabled", "N");
 xmlDocument.setParameter("callout", getOnChangeCode());
 }
 if (getData("IsMandatory").equals("Y"))
 xmlDocument.setParameter("required", "true");
 else
 xmlDocument.setParameter("required", "false");

 return replaceHTML(xmlDocument.print());
 }

 public String newMode() {
 XmlDocument xmlDocument = getReportEngine().readXmlTemplate(
 "org/openbravo/wad/controls/WADRadioButton").createXmlDocument();

 xmlDocument.setParameter("columnName", getData("ColumnName"));
 xmlDocument.setParameter("columnNameInp", getData("ColumnNameInp"));

 if (getData("IsReadOnly").equals("Y") || getData("IsReadOnlyTab").equals("Y")) {
 xmlDocument.setParameter("disabled", "Y");
 xmlDocument.setParameter("logChanges", "");
 xmlDocument.setParameter("disabledFalse", "return false;");
 } else {
 xmlDocument.setParameter("disabled", "N");
 xmlDocument.setParameter("callout", getOnChangeCode());
 }
 if (getData("IsMandatory").equals("Y"))
 xmlDocument.setParameter("required", "true");
 else
 xmlDocument.setParameter("required", "false");

 return replaceHTML(xmlDocument.print());
 }

 public String toXml() {
 StringBuffer text = new StringBuffer();
 if (getData("IsParameter").equals("Y")) {
 if (getData("IsDisplayed").equals("N")) {
 text.append("<PARAMETER id=\"").append(getData("ColumnName")).append("\" name=\"").append(
 getData("ColumnName")).append("\" attribute=\"value\"/>");
 } else {
 text.append("<PARAMETER id=\"").append(getData("ColumnName")).append("\" name=\"").append(
 getData("ColumnName")).append("\" boolean=\"checked\" withId=\"paramCheck\"/>");
 }
 } else {
 if (getData("IsDisplayed").equals("N")) {
 text.append("<FIELD id=\"").append(getData("ColumnName")).append("\" attribute=\"value\">");
 text.append(getData("ColumnName")).append("</FIELD>");
 } else {
 text.append("<FIELD id=\"").append(getData("ColumnName")).append(
 "\" boolean=\"checked\" withId=\"paramCheck\">");
 text.append(getData("ColumnName")).append("</FIELD>");
 }
 }
 return text.toString();
 }

 public String toJava() {
 return "";
 }

 public String getDefaultValue() {
 return "N";
 }

 public boolean isText() {
 return true;
 }
}
  • WADRadioButton.html

<?xml version="1.0" encoding="UTF-8" ?>

<FIELD_TMP>
 <div id="xx_inp">
 <span><input type="radio" name="inpxx" id="xx" value="Y" onchange="return true;" onclick="changeToEditingMode('force');logChanges(this);xx();return true;" required="false"/></span>
 </div>
</FIELD_TMP>

  • WADRadioButton.xml

<?xml version="1.0" encoding="UTF-8"?>

<REPORT>
 <template file="WADRadioButton.html"/>
 <PARAMETER id="paramChecked" name="checked" default="Y"/>

 <PARAMETER id="xx_inp" name="columnName" attribute="id" replace="xx"/>
 <PARAMETER id="xx" name="columnName" attribute="id" replace="xx"/>
 <PARAMETER id="xx" name="columnNameInp" attribute="name" replace="xx"/>
 <PARAMETER id="xx" name="callout" attribute="onclick" replace="xx();" default=""/>
 <PARAMETER id="xx" name="required" attribute="required"/>
 <PARAMETER id="xx" name="disabled" boolean=" onclick='return false;' readonly=true" withId="paramChecked"/>
 <PARAMETER id="xx" name="logChanges" attribute="onclick" replace="logChanges(this);" default="logChanges(this);"/>
 <PARAMETER id="xx" name="disabledFalse" attribute="onclick" replace="return true;" default="return true;"/>

 <DISCARD id="discard"/>
</REPORT>

In src/org/openbravo/reference/ui add the following files

  • UIRadioButton.java

/*
 @author: Shankar Balachandran
*/
package org.openbravo.reference.ui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;

import javax.servlet.ServletException;

import org.openbravo.base.secureApp.VariablesSecureApp;
import org.openbravo.erpCommon.businessUtility.BuscadorData;

public class UIRadioButton extends UIReference {
 public UIRadioButton(String reference, String subreference) {
 super(reference, subreference);
 }

 public void generateFilterHtml(StringBuffer strHtml, VariablesSecureApp vars,
 BuscadorData fields, String strTab, String strWindow, ArrayList<String> vecScript, Vector<Object> vecKeys) throws IOException, ServletException {
 UIList list = new UIList("17", "47209D76F3EE4B6D84222C5BDF170AA2");
 list.generateFilterHtml(strHtml, vars, fields, strTab, strWindow, vecScript, null);
 }

 public void generateFilterAcceptScript(BuscadorData field, StringBuffer params,
 StringBuffer paramsData) {
 UITableDir tableDir = new UITableDir(reference, subReference);
 tableDir.generateFilterAcceptScript(field, params, paramsData);
 }
}

In web/skins/Default/Common

  • Add the Radio Button Folder with images

In web/skins/Default, in Openbravo_ERP_250.css add the following Code.

 


/*Custom Code Developed by Shankar 	Balachandran*/
/*
*************************
* Radio Button
*************************
*/
.dojoHtmlRadioButton {
border: 0px;
width: 16px;
height: 16px;
margin: 2px;
vertical-align: middle;
}
.dojoHtmlRadioButtonOn {
background-image: 	url(Common/RadioButton/Enabled.png) ;
}
.dojoHtmlRadioButtonOff {
background-image: 	url(Common/RadioButton/Simple.png) ;
}
.dojoHtmlRadioButtonDisabledOn {
background-image: 	url(Common/RadioButton/Disabled.png) ;
}
.dojoHtmlRadioButtonDisabledOff {
background-image: 	url(Common/RadioButton/Enabled.png) ;
}
.dojoHtmlRadioButtonOnHover {
background-image: 	url(Common/RadioButton/Simple.png) ;
}
.dojoHtmlRadioButtonOffHover {
background-image: 	url(Common/RadioButton/Simple.png) ;
}
.RadioButton_NOT_focused, 	.Radio_NOT_focused {
}
.RadioButton_container_NOT_focused, 	.Radio_container_NOT_focused {
padding: 0px;
margin: 0px;
width: 0px;
height: 0px;
border-style: solid;
border-width: 2px;
border-color: transparent;
}
.RadioButton_focused, 	.Radio_focused {
border: 2px solid #4D98CA;
outline-style: solid;
outline-width: 2px;
outline-color: #4D98CA;
}
.RadioButton_container_focused, 	.Radio_container_focused {
border-style: solid;
border-width: 2px;
border-color: transparent;
}

Then you have to create a base reference in the Application for the Radio Button. Below is a screen shot for reference.

You can assign the reference to any column that you want. I assigned it to the ”Default” field in the Module Window. Attached below is the screen shot of the field mapping.

Then you can “compile.complete.deploy” and then check the Module Window for the change. Attached below is the Screen shot with the Radio Button in Disabled and Enabled states.

Radio Button Disabled:

Radio Button Enabled:

Note:

 

  1. Option buttons are best utilised with the Button Group and they are least useful when used as individual items.
  2. I tried creating the same in RC4. And in the new UI, all I got was a text box with default value ‘False’. Not sure what piece I missed. But when I viewed it through the classic mode option, (URL/?mode=classic), I was able to view the Radio Button correctly.
For more external reference examples, refer here.

Retrieving Parameters for DAL Process and Callouts in OpenbravoERP

Process:

In OpenbravoERP, when we write DAL Process, the first thing that we would need are the input parameters with which we can operate on the Window. By default there are some key parameters passed to the process bundle. They are:

1. Record ID

2. Tab Id

3. Client ID

4. Org ID

These values are presented to the user as key-value pairs. They can be retrieved as provided below:


String id=(String) bundle.getParams().get("TDS_Process_Pay_ID");
String id=(String) bundle.getParams().get("tabId");

The Catch here is that the key-value pairs are Case Sensitive. So the case of your name matters. But more often than not we cannot guess the case of our element variables. Instead of playing the guessing game you can use a very useful method provided in the same process bundle class, which is bundle.getParamsDefalated().This method returns all the process parameters that can be used in the process as a single string delimited by {[key1,value1]}. One example string that was retrieved is provided here.

Bundle {“map”:{“entry”:[{“string”:[“adOrgId”,””]},{“string”:[“tabId”,”9EB442F0BD9141319FAF085EF30D7CC9″]},{“string”:[“TDS_Process_Pay_ID”,”FF8081812EB2DA4C012EB2DD8117001A”]},{“string”:[“adClientId”,””]}]}}

Using this you can make sure you provide the right name to retrieve the process parameters.
Callout:

Callouts are a cool feature in Openbravo that helps us in defaulting fields and validating them at runtime. There is a simplecallout class defined in Openbravo using which we can extend and write our own callouts easily and effectively.For basics about developing callouts refer here. Even in callouts you have to retrieve the field’s value that you want to operate upon and set in the same manner. More often I see people confusing themselves between the parameter for Callout and process. The input field is usually prefixed  by ‘inp’ and the variable names are camel cased.For eg if the database field name is ‘first_name’, the field can be retrieved using the following command,

</pre>
String firstName = info.getStringParameter("inpfirstName",null);

And in case of Numeric fields, this command can be used.

BigDecimal noofbed = info.getBigDecimalParameter("inpnoOfBed");

And its easily a best practice to include logger so that you can record the status of the Process/Callout. You have to import the org.apache.log4j.Logger for this purpose. The logger can be instantiated and used as follows:

private static Logger log = Logger.getLogger(TrialProgram.class);
log.info("Displaying Sample Information");

Changing User Interface modes in Openbravo 3.0

OpenbravoERP 3.0 has brought a radical change to its User interface in its latest release 3.0. But like ardent developers I felt the 2.50 User Interface to be more suited for rapid development and I like the 2.50-3.0 Compatibility User interface for regular working. The buttons and the overall setup was pretty cool in it. Just when I thought there was no way to switch back, I came across this wiki link http://wiki.openbravo.com/wiki/ERP/3.0/Developers_Guide/How_To_Switch_to_Classic_Mode.

Though by default the users are provided with the 3.0 user interface, they have the option of reverting to the 2.50 User Interface mode or the 2.50-3.0 compatibility mode.I will present a simple screen shot of each mode and discuss its pro’s and con’s.

2.50 User Interface Mode:

2.50 User Interface Mode

2.50 User Interface Mode

Type the Url like this in your browser to switch to the Classic User interface.

http://localhost:8040/openbravo/security/Menu.html?noprefs=true

Pros:

  • Clean User Interface.
  • Classic left side menus

Cons:

  • Limited space for actual content
  • Design pretty old
  • Not much suitable for fast editing

2.50-3.0 Compatibility mode:

 

2.50-3.0 Compatibility Mode

2.50-3.0 Compatibility Mode

Pros:

  • Web based look
  • Clean UI, more space for actual content
  • Widgets for integrating other web services

Cons:

  • Not suitable for fast editing
  • Menu structures are difficult to fathom for 2.50 users.

3.0 latest User Interface:

 

3.0 RC4 latest User interface

3.0 RC4 latest User interface

Pros:

  • Edit in grid.
  • View child simultaneously.
  • Data operations like excel, formulae, adding runtime columns
  • User configurable widgets for Ob data.

Cons:

  • Buttons on top are little unclear at times when they have to be done in a sequence
  • The buttons errors out many times when tried in form mode. Works properly in grid mode.
  • The form alignment is still messy when there are more fields with display logics involved(compared to the other 2 versions)
  • Not Developer friendly  (I did not find the field sequence tab at all, at times edit in grid did not save, when i tried deleting multiple values it shows success, but records are not deleted)

Having said all this, I think the 3.0 is the future and I am sure they will clear the bugs and make it the preferred UI for many like me.And with more and more User Interface enhancements, I think working with Openbravo would be more like gaming than working..:)

Happy Working…