訂單與進出貨單的數量控管 MatchPO

下一個採購物料 A,數量 10 個。
收貨時,可以分批收貨。每次進 10個以下。合計總數不能超過 10個。

問題來了,有些特殊情況,需要超收怎麼辦?例如,供應商會多送一些當損耗。
嚴格處理的話,可以拆單收取。
簡易的操作,iDempiere 有預留系統參數,可以把MatchPO 檢查關掉。
登入後台 System , 在 System Configurator 搜尋系統參數 VALIDATE_MATCHING_TO_ORDERED_QTY
設為 N 即可不檢核。

下面是超收的範例 Purchase Order 明細。原訂購4個,實際收 15個。

Leave a comment

iDempiere plug-in project

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.idempiere</groupId>
	<artifactId>org.idempiere.parent</artifactId>
	<version>7.1.0-SNAPSHOT</version>
	<relativePath>../idempiere2020/org.idempiere.parent/pom.xml</relativePath>
    </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>tw.aierp.aps</groupId>
  <artifactId>tw.aierp.aps</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
    <parent>
        <groupId>org.idempiere</groupId>
	<artifactId>org.idempiere.parent</artifactId>
	<version>7.1.0-SNAPSHOT</version>
	<relativePath>../idempiere2020/org.idempiere.parent/pom.xml</relativePath>
    </parent>

修改pom.xml 插入 <parent> </parent>標籤

MyProcessFactory.java

package tw.aierp.aps.factories;
import org.adempiere.base.IProcessFactory;
import org.compiere.process.ProcessCall;

import tw.aierp.aps.process.CopyPlanMonth;
public class MyProcessFactory implements IProcessFactory {

	@Override
	public ProcessCall newProcessInstance(String className) {
		if(className == null)
			return null;
		if(className.equals(CopyPlanMonth.class.getName()))
			return new CopyPlanMonth();
		return null;	
	}

}
Leave a comment

Jasperreport Install Extension Font

Add new Font in Jasper studio setting.
Window -> Preferences -> Jaspersoft Studio -> Fonts

Family Name: Arial Unicode MS

True Type (.ttf) /home/ray/JaspersoftWorkspace/font/ARIALUNI.TTF

PDF Encoding: identity-H (Unicode with horizontal writing)

Leave a comment

Workflow中等待結點的推進

說明:

若Workflow Node 結點中設定等待時間. iDempiere 預設情況下,就算時間到了, 也不會將流程往前推進.
目前設計是由相關權責人員到簽核畫面去按確認才會往下走.

不過,我有一個實際的案例, 需要用到 Wait Timeout 自動往下走.

情境如下:
加班單送出申請後, 系統會自動檢查該員工是否有打下班卡,以核對加班單的有效性.
但是,真實使用情境,通常員工加班完後會先在自己的電腦操作ERP申請完加班申請, 這時候需要先等待一時間等員工離開公司時的打卡紀錄.
另外,若沒有打卡紀錄,系統會通知員工出勤紀錄有誤,再等待半天時間等員工補登.
下面流程兩紅色框起來的兩個 Node 會運用到Timeout and Next 的自動功能.

實作法法:
撰寫一個 IProcess 並安裝到 Scheduler 讓它自動執行.

package tw.ninniku.trade.process;

import java.math.BigDecimal;
import java.net.UnknownHostException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;

import javax.xml.bind.JAXBException;
import javax.xml.datatype.DatatypeConfigurationException;

import org.compiere.db.CConnection;
import org.compiere.model.I_M_ProductionPlan;
import org.compiere.model.MClient;
import org.compiere.model.MInOut;
import org.compiere.model.MInOutLine;
import org.compiere.model.MProductCategory;
import org.compiere.model.MProduction;
import org.compiere.model.MProductionPlan;
import org.compiere.model.MRole;
import org.compiere.model.MSysConfig;
import org.compiere.model.MUser;
import org.compiere.model.Query;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.StateEngine;
import org.compiere.process.SvrProcess;
import org.compiere.util.AdempiereUserError;
import org.compiere.util.DB;
import org.compiere.util.EMail;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.wf.MWFActivity;

import tw.ninniku.einvoice.A0401.A0401Builder;
import tw.ninniku.trade.model.MTradeInvoice;

/**
 * 
 * 針對 HR 模組 workflow node 去推動
 * @author Ray Lee
 *
 */
public class CheckWaitingWorkflow extends SvrProcess {

	/**	Open Activities				*/
	private MWFActivity[] 		m_activities = null;
	/**	Current Activity			*/
	private MWFActivity 		m_activity = null;
	/**	Current Activity			*/
	private int	 				m_index = 0;
	private String host = null;

	protected void prepare() {
		
		ProcessInfoParameter[] para = getParameter();
		for (int i = 0; i < para.length; i++)
		{
			String name = para[i].getParameterName();
			if ("Host".equals(name))
				host = para[i].getParameterAsString();
			else
				log.log(Level.SEVERE, "Unknown Parameter: " + name);		
		}
	}	//prepare

	@Override
	protected String doIt() throws Exception {

		String hostname;
		try {
			hostname = java.net.InetAddress.getLocalHost().getHostName();
			if(!hostname.equals(host))
				return "Non-specified host.";
			updateActivities();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		
		return "Done";
	}

	public int updateActivities()
	{
		int counter = 0;
		String sql = "select * from AD_WF_Activity aa"
				 +" where wfstate = 'OS'" 
				 + " and endwaittime < now()" 
				 + " and endwaittime is not null"
				 + " and isactive = 'Y'"
				 + " and exists ( select * from  AD_WF_Node where AD_WF_Node_id = aa.AD_WF_Node_id and action = 'Z' and waittime != 0 and EntityType = 'TG02') ";

		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try
		{
			pstmt = DB.prepareStatement (sql, get_TrxName());

			rs = pstmt.executeQuery ();
			while (rs.next ())
			{
				MWFActivity activity = new MWFActivity(Env.getCtx(), rs, null);
				activity.setWFState(StateEngine.STATE_Running);
				activity.setWFState(StateEngine.STATE_Completed);
				counter++;
			}
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql, e);
		}
		finally
		{
			DB.close(rs, pstmt);
			rs = null; pstmt = null;
		}

		return counter;
	}	//	loadActivities	
}
Leave a comment

關閉Ubuntu Desktop GUI

To disiable GUI

sudo systemctl set-default multi-user.target

To enable GUI again issue the command:

sudo systemctl set-default graphical.target

To start Gnome session on a system without a current GUI just execute:

sudo systemctl start gdm3.service

Leave a comment

iDempiere ERP – Drop Shipment 三角交易總整理

三角交易情境說明

你有一家商店(簡稱 Y)接收訂單, 有一個客戶(簡稱C)向你下單. 你接到單後,委託供應商 (簡稱S)出貨. 單據關係如下:
C: Purchase Order —– Y:Sales Order
Y: Purchase Order —– S:Sales Order
S: Shipment —— Y: Receipt
S: AR Invoice ——– Y: AP Invoice
Y:Shipment ——- C: Receipt
Y:AR Invoice ——— C: AP Invoice

立帳模式有兩種:佣金法及銷貨法


使用時機,若産品的品質及權責在供應商時,使用佣金法立帳.責任在自己企業時,則用銷貨法立帳.
佣金法比較適合應用在沒有自己品牌的經銷商.像經銷 Apple iPhone, Sony LED TV, Dell 電腦等等. 原廠有自己的産品責任.

iDempiere 搭配Document Counter 自動完成銷貨法相關單據

1.若供應商非關係企業(非ERP內的Org)時
1.1可以利用 Web Service 接收供應商送來的出貨單資訊後,自動産生收料單及AP Invoice.再産生出貨單及AR Invoice.
1.2 若供應商ERP系統無法串接時.可以手動産生收料單後抛 AP Invoice ,再用Sales Order 抛轉 Shipment 及 AR Invoice.

2. 若供應商為關係企業時 
2.1 可以直接利用設定Document Coutner自動産收料單.再由收料單自動抛轉進貨單據. 當系統發現是 DropShipment 文件時, 會自動産生出貨單. 來完成採購及銷售循環.

抛轉使用欄位參考
Document Counter 産生的單據會利用 Ref_主鍵名稱來紀錄相關的單據ID.

AR Invocie Fact (System Default Account)

Shipment Fact (System Default Account)

Leave a comment