Here is a scenario:

Write a callout for payment window to calculate following withholding Taxes & Security on Payment Voucher:

  1. GST

  2. PST

  3. Income Tax

  4. Security

Note: After deduction of taxes, the Payment Amount will become lesser than Invoice Amount but the iDempiere doesn’t knows it becasue we are doing calculations using custom Callouts. Due to it, there will be a difference between invoice amount and payment amount that must be inserted into WriteOff Amount. Otherwise, the difference will remain as arrears and the invoice will stay in Accounts Payable. Therefore, the difference of Invoice Amount and Payment Amount should be inserted into WriteOff Amount using Callout.

Following are the steps to achieve this task:

    1. Create Columns in c_payment table that will contain the tax amounts, i.e. GST, PST, Income Tax, Security.
    2. Place the fields in Payment window and set their positions, accordingly.
    3. Open file in Eclipse, located in org.adempiere.base.callout –> src –> org.compiere.model –>
    4. You can write your callout related to payment window in here.
    5. Here is a sample callout to calculate withholding taxes:

public String incomeTaxCal(Properties ctx, int WindowNo, GridTab mTab,
GridField mField, Object value, Object oldValue)
int c_bpartner_id = Integer.parseInt((String) mTab.getValue("c_bpartner_id").toString());
Double payamount = Double.parseDouble(value.toString());
Double pstTax=null,salesTax=null,incomeTax = null,security=null;
//String colName = mField.getColumnName();
String sql = "select partner_type from adempiere.c_bpartner as c where c.c_bpartner_id="+c_bpartner_id;
PreparedStatement pstmt = null;
ResultSet rs = null;
pstmt = DB.prepareStatement(sql, null);
//pstmt.setInt(1, c_bpartner_id);
rs = pstmt.executeQuery();
if (
String txt = rs.getString("partner_type");
if (txt.equals("private"))
incomeTax = payamount*0.04;
//pstTax = payamount*0.04;
mTab.setValue("INCOMETAX", new BigDecimal(incomeTax));
//mTab.setValue("PST", pstTax);
else if (txt.equals("public"))
incomeTax = payamount*0.04;
//pstTax = payamount*0.05;
mTab.setValue("INCOMETAX", new BigDecimal(incomeTax));
//mTab.setValue("PST", pstTax);
else if (txt.equals("in-aop"))
incomeTax = payamount*0.045;
//pstTax = payamount*0.06;
mTab.setValue("INCOMETAX", new BigDecimal(incomeTax));
//mTab.setValue("PST", pstTax);
catch (SQLException e)
log.log(Level.SEVERE, sql, e);
DB.close(rs, pstmt);
rs = null;
pstmt = null;
return "";
public String saleTaxCal(Properties ctx, int WindowNo, GridTab mTab,
GridField mField, Object value, Object oldValue)
Double payamount = Double.parseDouble(value.toString());
Double saletax = payamount*0.020;
mTab.setValue("SalesTax", new BigDecimal(saletax));
return "";
public String totalAmount(Properties ctx, int WindowNo, GridTab mTab,
GridField mField, Object value, Object oldValue)
BigDecimal pst = (BigDecimal)mTab.getValue("PST");
BigDecimal Security = (BigDecimal)mTab.getValue("Security");
BigDecimal SalesTax = (BigDecimal)mTab.getValue("salestax");
BigDecimal IncomeTax = (BigDecimal)mTab.getValue("IncomeTax");
BigDecimal payamount = (BigDecimal)mTab.getValue("amount_Invoice");
Double sum=payamount.doubleValue() - (pst.doubleValue()+Security.doubleValue()+SalesTax.doubleValue()+IncomeTax.doubleValue());
mTab.setValue ("PayAmt", new BigDecimal(sum));
return "";


  1. Once this code is placed, build the Project by running mvn verify command in terminal or Git Bash. Open directory of iDempiere having source code and run the command.
  2. Your callout will be implemented.
  3. But if you want to implement this callout in another installation of iDempiere, then follow these steps:
  4. Open the root directory of iDempiere in which you have implemented callout.
  5. Copy the file: org.adempiere.base.callout_x.x.x.x.x.x.jar placed in myexperiment\org.idempiere.p2\target\products\org.adempiere.server.product\linux\gtk\x86_64\plugins.
  6. Now copy the same file from target iDempiere installation directory to another folder.
  7. Rename the updated .jar file with the name of target .jar file.
  8. Now paste the updated & renamed .jar file in the above mentioned directory of targeted iDempiere.
  9. Now build the project by running mvn verify command.
  10. Your callout will be implement.

Note: If anything goes wrong then again replace the .jar file with the original one and build the project again.


Scenario: What if the iDempiere is hosted on a linux based virtual server that can only be accessed via VPN using SSH client?

  1. Well, the best idea is to install GUI to linux server or use GUI based OS. I recommend Ubuntu Desktop.
  2. You can install teamviewer for unattended access to the virtual server. Set a password for your server and you let the teamviewer run as a service.
  3. Now upload the updated .jar file in Downloads folder of the remote server.
  4. Now open the root directory of iDempiere, most probably, it will be opt/idempiere-server. Open the plugins folder and copy the file org.adempeire.base.callout_x.x.x.x.x.jar file.
  5. Paste the file in Downloads folder.
  6. Now rename the uploaded file with the copied file and save the copied file for later use to any directory.
  7. Now the thing we need to do is replace the original file with the uploaded file in the root directory but we cannot do it without admin access. To achieve this task:
  8. Open terminal and run following commands:
    1. To have admin access: sudo su and type admin password.
    2. Access Downloads folder: cd/home/user-name/Downloads/
    3. Delete org.adempiere.base.callout_x.x.x..x.x.jar from opt/idempiere-server/plugins/
    4. Copy and paste uploaded and renamed .jar file to plugins folder: cp org.adempiere.base.callout_x.x.x..x.x.jar -r /opt/idempiere-server/plugins/
    5. Now you can open directory & check, your file is replaced.
    6. Open directory: cd opt/idempiere-server/plugins/
    7. Get list of files: ls
    8. Your uploaded .jar file with updated name will be available in the folder.
    9. Open root directory: cd opt/idempiere-server and build project by running mvn verify command.
  9. Your callout will be implemented.

Leave a Reply