Junge Frau im Büro ist mit der Arbeit überfordert. Burnout bei Arbeit oder Studium.

The code implements an undo mechanism for accounting staff to reverse their actions. This can be useful in situations where a mistake has been made and needs to be corrected. The code also defines valid actions that can be taken on the document depending on its current status.


This is a Java code for a custom implementation of a depreciation entry in an ERP system, extending the base class MDepreciationEntry and implementing the DocOptions interface.

The class overrides the voidIt() method, which deletes the accounting entry of the document and updates the MDepreciationExp table to remove the ParentID and set the “processed” flag to ‘N’. The method also checks if the period is open before deleting the accounting entry.

The customizeValidActions() method is also implemented to customize the valid actions available for this document based on its status. For example, if the document status is “Completed”, the only valid action available is to void the document.

package tw.ninniku.model;

import java.sql.ResultSet;
import java.util.Properties;
import java.util.logging.Level;

import org.compiere.model.MDepreciationExp;
import org.compiere.model.MPeriod;
import org.compiere.process.DocOptions;
import org.compiere.process.DocumentEngine;
import org.compiere.util.DB;

public class MDepreciationEntry extends org.compiere.model.MDepreciationEntry  implements DocOptions {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public MDepreciationEntry(Properties ctx, int A_Depreciation_Entry_ID, String trxName) {
		super(ctx, A_Depreciation_Entry_ID, trxName);
		// TODO Auto-generated constructor stub
	}

	public MDepreciationEntry(Properties ctx, ResultSet rs, String trxName) {
		super(ctx, rs, trxName);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean voidIt() {
		/**
		 *  1.Delete the accounting entry of this document.
		 *  2.Reactivate the depreciation document and remove the ParentID.
		 */
		MPeriod.testPeriodOpen(getCtx(), getDateAcct(), getC_DocType_ID(), getAD_Org_ID());
		 String sql = "delete from fact_acct where ad_table_id = ? and record_id = ?";
	     DB.executeUpdateEx(sql, new Object[]{MDepreciationEntry.Table_ID,getA_Depreciation_Entry_ID()}, get_TrxName());
		return unprocessLines();
	}
	private boolean unprocessLines()
	{
		String sql = "UPDATE " + MDepreciationExp.Table_Name + " SET "
						+ MDepreciationExp.COLUMNNAME_A_Depreciation_Entry_ID + "=NULL  , processed = 'N' "
					+ " WHERE "
						+ MDepreciationExp.COLUMNNAME_A_Depreciation_Entry_ID + "=?";
		int id = get_ID();
		if (id <= 0) 
		{ // Use old ID is current ID is missing (i.e. object was deleted)
			id = get_IDOld();
		}
		int no = DB.executeUpdateEx(sql, new Object[]{id}, get_TrxName());
		if (log.isLoggable(Level.FINE)) log.fine("Updated #" + no);
		if(no >  0)
			return true;
		return false;
	}

	@Override
	public int customizeValidActions(String docStatus, Object processing, String orderType, String isSOTrx,
			int AD_Table_ID, String[] docAction, String[] options, int index) {
		// TODO Auto-generated method stub
				if (options == null)
					throw new IllegalArgumentException("Option array parameter is null");
				if (docAction == null)
					throw new IllegalArgumentException("Doc action array parameter is null");


				//	Approval required           ..  NA
				if (docStatus.equals(DocumentEngine.STATUS_NotApproved))
				{
					//options[index++] = DocumentEngine.ACTION_Prepare;
					options[index++] = DocumentEngine.ACTION_Void;
					options[index++] = DocumentEngine.ACTION_Complete;
				}
				//	Draft/Invalid				..  DR/IN
				else if (docStatus.equals(DocumentEngine.STATUS_Drafted)
					|| docStatus.equals(DocumentEngine.STATUS_Invalid))
				{
					options[index++] = DocumentEngine.ACTION_Complete;
			 	//	options[index++] = DocumentEngine.ACTION_Prepare;
					options[index++] = DocumentEngine.ACTION_Void;
				}
				//	In Process                  ..  IP
				else if (docStatus.equals(DocumentEngine.STATUS_InProgress)
					|| docStatus.equals(DocumentEngine.STATUS_Approved))
				{
					options[index++] = DocumentEngine.ACTION_Complete;
					//options[index++] = DocumentEngine.ACTION_Void;
				}
				//	Complete                    ..  CO
				else if (docStatus.equals(DocumentEngine.STATUS_Completed))
				{
					options[index++] = DocumentEngine.ACTION_Void;
					docAction[0] = DocumentEngine.ACTION_Void;
				}
				//	Waiting Payment
				else if (docStatus.equals(DocumentEngine.STATUS_WaitingPayment)
					|| docStatus.equals(DocumentEngine.STATUS_WaitingConfirmation))
				{
					//options[index++] = DocumentEngine.ACTION_Void;
					//options[index++] = DocumentEngine.ACTION_Prepare;
				}
				//	Closed, Voided, REversed    ..  CL/VO/RE
				else if (docStatus.equals(DocumentEngine.STATUS_Closed)
					|| docStatus.equals(DocumentEngine.STATUS_Voided)
					|| docStatus.equals(DocumentEngine.STATUS_Reversed))
					return 0;
				
				return index;
				//return 0;
	}
}

By Ray Lee (System Analyst)

iDempeire ERP Contributor, 經濟部中小企業處財務管理顧問 李寶瑞

Leave a Reply

Your email address will not be published. Required fields are marked *