move branch adempire311 to trunk
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/server"/>
|
||||
<classpathentry kind="src" path="src/main/servlet"/>
|
||||
<classpathentry kind="src" path="src/main/ejb"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="src" path="/tools"/>
|
||||
<classpathentry kind="src" path="/dbPort"/>
|
||||
<classpathentry kind="src" path="/base"/>
|
||||
<classpathentry kind="src" path="/looks"/>
|
||||
<classpathentry kind="lib" path="/interfaces/Interfaces.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/print"/>
|
||||
<classpathentry kind="output" path="build/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configurations/>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>serverRoot</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>base</project>
|
||||
<project>dbPort</project>
|
||||
<project>looks</project>
|
||||
<project>server</project>
|
||||
<project>tools</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configurations/>
|
|
@ -0,0 +1,19 @@
|
|||
@Title Build Adempiere Root
|
||||
@Rem $Header: /cvsroot/adempiere/serverRoot/RUN_build.bat,v 1.11 2005/09/16 00:50:14 jjanke Exp $
|
||||
|
||||
@CALL ..\utils_dev\myDevEnv.bat
|
||||
@IF NOT %ADEMPIERE_ENV%==Y GOTO NOBUILD
|
||||
|
||||
@echo Cleanup ...
|
||||
@"%JAVA_HOME%\bin\java" -Dant.home="." %ANT_PROPERTIES% org.apache.tools.ant.Main clean
|
||||
|
||||
@echo Building ...
|
||||
@"%JAVA_HOME%\bin\java" -Dant.home="." %ANT_PROPERTIES% org.apache.tools.ant.Main main
|
||||
|
||||
@Echo Done ...
|
||||
@sleep 60
|
||||
@exit
|
||||
|
||||
:NOBUILD
|
||||
@Echo Check myDevEnv.bat (copy from myDevEnvTemplate.bat)
|
||||
@Pause
|
|
@ -0,0 +1,18 @@
|
|||
# Module compiling script
|
||||
# Ported from Windows script Marek Mosiewicz<marek.mosiewicz@jotel.com.pl>
|
||||
|
||||
|
||||
SAVED_DIR=`pwd` #save current dir
|
||||
cd `dirname $0`/../utils_dev #change dir to place where script resides - doesn not work with sym links
|
||||
UTILS_DEV=`pwd` #this is adempiere source
|
||||
cd $SAVED_DIR #back to the saved directory
|
||||
|
||||
. $UTILS_DEV/myDevEnv.sh #call environment
|
||||
echo done
|
||||
if [ ! $ADEMPIERE_ENV==Y ] ; then
|
||||
echo "Can't set developemeent environemnt - check myDevEnv.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo running Ant
|
||||
$JAVA_HOME/bin/java -Dant.home="." $ANT_PROPERTIES org.apache.tools.ant.Main
|
|
@ -0,0 +1,33 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>JBuilder Project ServerRoot.jpx</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Project ServerRoot Notes</h1>
|
||||
<hr><table border="0">
|
||||
<tr><th align="left" valign="top">Title:</th><td align="left" valign="top">
|
||||
<!-- Type Title below -->
|
||||
|
||||
</td></tr>
|
||||
<tr><th align="left" valign="top">Author:</th><td align="left" valign="top">
|
||||
<!-- Type Author below -->
|
||||
|
||||
</td></tr>
|
||||
<tr><th align="left" valign="top">Company:</th><td align="left" valign="top">
|
||||
<!-- Type Company below -->
|
||||
|
||||
</td></tr>
|
||||
<tr><th align="left" valign="top">Description:</th><td align="left" valign="top">
|
||||
<!-- Type Description below -->
|
||||
|
||||
</td></tr>
|
||||
</table><hr>
|
||||
<h2>Things to do... </h2>
|
||||
<ol>
|
||||
<!-- Edit this section to keep track of your to do items -->
|
||||
<li>First
|
||||
<li>Second
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,235 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- ============================================= -->
|
||||
<!-- Adempiere Server Root -->
|
||||
<!-- ============================================= -->
|
||||
<!-- $Header: /cvs/adempiere/serverRoot/build.xml,v 1.4 2006/06/10 21:58:02 jjanke Exp $-->
|
||||
|
||||
<project name="adempiereRoot" default="main" basedir=".">
|
||||
|
||||
<property environment="env"/>
|
||||
|
||||
<property name="xdoclet.home" value="../tools" />
|
||||
<property name="xdoclet.force" value="false" />
|
||||
<property name="ejb.version" value="2.0" />
|
||||
|
||||
<property name="src.dir" value="${basedir}/src"/>
|
||||
<property name="src.main.dir" value="${src.dir}/main"/>
|
||||
<property name="src.ear.dir" value="${src.dir}/ear"/>
|
||||
<property name="src.ejb.dir" value="${src.main.dir}/ejb"/>
|
||||
<property name="src.servlet.dir" value="${src.main.dir}/servlet"/>
|
||||
<property name="src.server.dir" value="${src.main.dir}/server"/>
|
||||
<property name="src.resources.dir" value="${src.dir}/resources"/>
|
||||
<property name="src.web.dir" value="${src.dir}/web"/>
|
||||
|
||||
<property name="build.dir" value="${basedir}/build"/>
|
||||
<property name="build.tmp.dir" value="${build.dir}/tmp"/>
|
||||
<property name="build.deploy.dir" value="${build.dir}/deploy"/>
|
||||
<property name="build.classes.dir" value="${build.dir}/classes"/>
|
||||
<property name="build.war.dir" value="${build.dir}/war"/>
|
||||
|
||||
<property name="interfaces.dir" value="../interfaces"/>
|
||||
<property name="src.interfaces.dir" value="../interfaces/src"/>
|
||||
<property name="build.interfaces.dir" value="../interfaces/classes"/>
|
||||
|
||||
|
||||
<target name="adempiereRootInit">
|
||||
<echo message="=========== Build Server Root"/>
|
||||
|
||||
<tstamp/>
|
||||
<uptodate property="interfaces.uptodate"
|
||||
targetfile="${interfaces.dir}/Interfaces.jar">
|
||||
<srcfiles dir="${src.ejb.dir}" includes="**/*.java"/>
|
||||
<srcfiles dir="${src.interfaces.dir}" includes="**/*.java"/>
|
||||
</uptodate>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<path id="xdoclet.path">
|
||||
<pathelement location="${xdoclet.home}/lib/ant.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/log4j.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/commons-logging.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/xdoclet-1.2.3.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/xdoclet-web-module-1.2.3.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/xdoclet-ejb-module-1.2.3.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/xjavadoc-1.1.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/xdoclet-xdoclet-module-1.2.3.jar" />
|
||||
<pathelement location="${xdoclet.home}/lib/commons-collections-3.1.jar" />
|
||||
</path>
|
||||
|
||||
<path id="base.path">
|
||||
<path refid="xdoclet.path"/>
|
||||
<pathelement location="../lib/Adempiere.jar" />
|
||||
<pathelement location="../lib/CSTools.jar" />
|
||||
<pathelement location="../tools/lib/j2ee.jar" />
|
||||
<pathelement location="${build.classes.dir}" />
|
||||
</path>
|
||||
|
||||
|
||||
<!-- =================================================================== -->
|
||||
<!-- Generates the necessary EJB classes and deployment descriptors -->
|
||||
<!-- =================================================================== -->
|
||||
<target name="adempiereRootXdoclet" depends="adempiereRootInit">
|
||||
<echo message="XDoclet=${xdoclet.home}"/>
|
||||
<echo message="UpToDate=${interfaces.uptodate}"/>
|
||||
|
||||
<taskdef
|
||||
name="ejbdoclet"
|
||||
classname="xdoclet.modules.ejb.EjbDocletTask"
|
||||
classpathref="base.path"/>
|
||||
|
||||
<ejbdoclet
|
||||
destdir="${src.interfaces.dir}"
|
||||
excludedTags="@version,@author"
|
||||
ejbspec="${ejb.version}"
|
||||
mergedir="${src.resources.dir}/xdoclet"
|
||||
force="${xdoclet.force}">
|
||||
<fileset dir="${src.ejb.dir}">
|
||||
<include name="**/*Bean.java"/>
|
||||
</fileset>
|
||||
<packageSubstitution packages="session,entity" substituteWith="interfaces"/>
|
||||
<homeinterface/>
|
||||
<localinterface/>
|
||||
<localhomeinterface/>
|
||||
<remoteinterface/>
|
||||
<deploymentdescriptor destdir="${build.dir}/META-INF"/>
|
||||
</ejbdoclet>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Compiles the source code -->
|
||||
<!-- =========================================== -->
|
||||
<target name="adempiereRootCompile" depends="adempiereRootXdoclet">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
|
||||
<!-- Compile all -->
|
||||
<javac
|
||||
destdir="${build.classes.dir}"
|
||||
debug="on"
|
||||
deprecation="off"
|
||||
optimize="on"
|
||||
classpathref="base.path">
|
||||
<src path="${src.ejb.dir}"/>
|
||||
<src path="${src.interfaces.dir}"/>
|
||||
<src path="${src.servlet.dir}"/>
|
||||
<src path="${src.server.dir}"/>
|
||||
</javac>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Creates the jar archives -->
|
||||
<!-- =========================================== -->
|
||||
<target name="adempiereRootJar" depends="adempiereRootCompile">
|
||||
<mkdir dir="${build.deploy.dir}"/>
|
||||
|
||||
<!-- Jar -->
|
||||
<jar
|
||||
jarfile="${build.deploy.dir}/adempiereRoot.jar">
|
||||
<fileset
|
||||
dir="${build.classes.dir}">
|
||||
</fileset>
|
||||
<fileset
|
||||
dir="${build.dir}"
|
||||
includes="META-INF/**">
|
||||
</fileset>
|
||||
<manifest>
|
||||
<attribute name="Specification-Title" value="AdempiereRoot"/>
|
||||
<attribute name="Specification-Version" value="${env.ADEMPIERE_VERSION}"/>
|
||||
<attribute name="Specification-Vendor" value="Adempiere"/>
|
||||
<attribute name="Implementation-Title" value="AdempiereRoot ${env.ADEMPIERE_VERSION}"/>
|
||||
<attribute name="Implementation-Version" value="${env.ADEMPIERE_VERSION} ${DSTAMP}-${TSTAMP}"/>
|
||||
<attribute name="Implementation-Vendor" value="${env.ADEMPIERE_VENDOR}"/>
|
||||
<attribute name="Implementation-URL" value="http://www.adempiere.com"/>
|
||||
<attribute name="Class-Path" value="Adempiere.jar AdempiereSLib.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
</target>
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Creates the war archives -->
|
||||
<!-- =========================================== -->
|
||||
<target name="adempiereRootWar" depends="adempiereRootJar">
|
||||
<war
|
||||
warfile="${build.deploy.dir}/adempiereRootBase.war"
|
||||
webxml="${src.web.dir}/WEB-INF/web.xml">
|
||||
<!-- copy from web -->
|
||||
<fileset dir="${src.web.dir}" excludes="**/web.xml,**/lib/**,**/classes/**"/>
|
||||
<!-- WEB-INF/lib -->
|
||||
<lib dir="${src.web.dir}/WEB-INF/lib"/>
|
||||
<manifest>
|
||||
<attribute name="Specification-Title" value="AdempiereRootWar"/>
|
||||
<attribute name="Specification-Version" value="${env.ADEMPIERE_VERSION}"/>
|
||||
<attribute name="Specification-Vendor" value="Adempiere"/>
|
||||
<attribute name="Implementation-Title" value="AdempiereRootWar ${env.ADEMPIERE_VERSION}"/>
|
||||
<attribute name="Implementation-Version" value="${env.ADEMPIERE_VERSION} ${DSTAMP}-${TSTAMP}"/>
|
||||
<attribute name="Implementation-Vendor" value="${env.ADEMPIERE_VENDOR}"/>
|
||||
<attribute name="Implementation-URL" value="http://www.adempiere.com"/>
|
||||
<attribute name="Class-Path" value="Adempiere.jar AdempiereSLib.jar"/>
|
||||
</manifest>
|
||||
</war>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Creates the interface archive -->
|
||||
<!-- =========================================== -->
|
||||
<target name="adempiereRootInterfaces" depends="adempiereRootCompile">
|
||||
|
||||
<!-- Copy MBeans to interfaces -->
|
||||
<copy todir="${src.interfaces.dir}">
|
||||
<fileset dir="${src.server.dir}" includes="**/*MBean.java"/>
|
||||
</copy>
|
||||
|
||||
<!-- Compile interfaces -->
|
||||
<mkdir dir="${build.interfaces.dir}"/>
|
||||
<javac
|
||||
srcdir="${src.interfaces.dir}"
|
||||
destdir="${build.interfaces.dir}"
|
||||
debug="off"
|
||||
deprecation="on"
|
||||
optimize="on"
|
||||
classpathref="base.path">
|
||||
</javac>
|
||||
<!-- Jar Interfaces -->
|
||||
<jar
|
||||
destfile="${interfaces.dir}/Interfaces.jar"
|
||||
basedir="${build.interfaces.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Deploy Server Files -->
|
||||
<!-- =========================================== -->
|
||||
<target name="adempiereRootDeployServer" depends="adempiereRootJar,adempiereRootWar,adempiereRootInterfaces">
|
||||
<copy todir="../lib">
|
||||
<fileset dir="${build.deploy.dir}"/>
|
||||
</copy>
|
||||
<copy file="${src.ear.dir}/application.xml"
|
||||
tofile="../lib/adempiereRoot.xml"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Creates the binary structure -->
|
||||
<!-- =========================================== -->
|
||||
<target name="main" depends="adempiereRootDeployServer">
|
||||
</target>
|
||||
|
||||
|
||||
<!-- =========================================== -->
|
||||
<!-- Cleans up the current build -->
|
||||
<!-- =========================================== -->
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}" failonerror="false"/>
|
||||
<!-- This is boring to delete these
|
||||
<delete>
|
||||
<fileset dir="${src.interfaces.dir}" includes="**/*.java"/>
|
||||
</delete>
|
||||
-->
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,5 @@
|
|||
@Rem API Documentation for Server
|
||||
|
||||
call ..\doc\documentation.bat "src\main\client;src\main\ejb;src\main\server;src\main\servlet" doc -private
|
||||
|
||||
@pause
|
|
@ -0,0 +1,4 @@
|
|||
org.compiere.client
|
||||
org.compiere.session
|
||||
org.compiere.server
|
||||
org.compiere.web
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project default="_generation_" name="Packaging Generator">
|
||||
<target name="_generation_" depends=""/>
|
||||
</project>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 1999-2005 Jorg Janke ComPiere, Inc.
|
||||
@version $Id: application.xml,v 1.3 2006/06/12 00:59:05 jjanke Exp $
|
||||
-->
|
||||
<application version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
|
||||
<display-name>adempiereRoot</display-name>
|
||||
<description>Adempiere Root</description>
|
||||
<module>
|
||||
<java>AdempiereSLib.jar</java>
|
||||
</module>
|
||||
<module>
|
||||
<java>Adempiere.jar</java>
|
||||
</module>
|
||||
<module>
|
||||
<ejb>adempiereRoot.jar</ejb>
|
||||
</module>
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>adempiereRoot.war</web-uri>
|
||||
<context-root>/admin</context-root>
|
||||
</web>
|
||||
</module>
|
||||
</application>
|
|
@ -0,0 +1,669 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.session;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import javax.ejb.*;
|
||||
import javax.sql.*;
|
||||
|
||||
import org.compiere.*;
|
||||
import org.compiere.acct.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.process.*;
|
||||
import org.compiere.util.*;
|
||||
import org.compiere.wf.*;
|
||||
|
||||
/**
|
||||
* Adempiere Server Bean.
|
||||
*
|
||||
* @ejb.bean name="adempiere/Server"
|
||||
* display-name="Adempiere Server Session Bean"
|
||||
* type="Stateless"
|
||||
* view-type="both"
|
||||
* transaction-type="Bean"
|
||||
* jndi-name="adempiere/Server"
|
||||
* local-jndi-name="adempiere/ServerLocal"
|
||||
*
|
||||
* @ejb.ejb-ref ejb-name="adempiere/Server"
|
||||
* view-type="both"
|
||||
* ref-name="adempiere/Server"
|
||||
* @ejb.ejb-ref ejb-name="adempiere/Server"
|
||||
* view-type="local"
|
||||
* ref-name="adempiere/ServerLocal"
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: ServerBean.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class ServerBean implements SessionBean
|
||||
{
|
||||
/** Context */
|
||||
private SessionContext m_Context;
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger(ServerBean.class);
|
||||
//
|
||||
private static int s_no = 0;
|
||||
private int m_no = 0;
|
||||
//
|
||||
private int m_windowCount = 0;
|
||||
private int m_postCount = 0;
|
||||
private int m_processCount = 0;
|
||||
private int m_workflowCount = 0;
|
||||
private int m_paymentCount = 0;
|
||||
private int m_nextSeqCount = 0;
|
||||
private int m_stmt_rowSetCount = 0;
|
||||
private int m_stmt_updateCount = 0;
|
||||
private int m_cacheResetCount = 0;
|
||||
private int m_updateLOBCount = 0;
|
||||
|
||||
/**
|
||||
* Get and create Window Model Value Object
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param ctx Environment Properties
|
||||
* @param WindowNo number of this window
|
||||
* @param AD_Window_ID the internal number of the window, if not 0, AD_Menu_ID is ignored
|
||||
* @param AD_Menu_ID ine internal menu number, used when AD_Window_ID is 0
|
||||
* @return initialized Window Model
|
||||
*/
|
||||
public GridWindowVO getWindowVO (Properties ctx, int WindowNo, int AD_Window_ID, int AD_Menu_ID)
|
||||
{
|
||||
log.info ("getWindowVO[" + m_no + "] Window=" + AD_Window_ID);
|
||||
// log.fine(ctx);
|
||||
GridWindowVO vo = GridWindowVO.create(ctx, WindowNo, AD_Window_ID, AD_Menu_ID);
|
||||
m_windowCount++;
|
||||
return vo;
|
||||
} // getWindowVO
|
||||
|
||||
|
||||
/**
|
||||
* Post Immediate
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param ctx Client Context
|
||||
* @param AD_Client_ID Client ID of Document
|
||||
* @param AD_Table_ID Table ID of Document
|
||||
* @param Record_ID Record ID of this document
|
||||
* @param force force posting
|
||||
* @param trxName transaction
|
||||
* @return null, if success or error message
|
||||
*/
|
||||
public String postImmediate (Properties ctx,
|
||||
int AD_Client_ID, int AD_Table_ID, int Record_ID, boolean force, String trxName)
|
||||
{
|
||||
log.info ("[" + m_no + "] Table=" + AD_Table_ID + ", Record=" + Record_ID);
|
||||
m_postCount++;
|
||||
MAcctSchema[] ass = MAcctSchema.getClientAcctSchema(ctx, AD_Client_ID);
|
||||
return Doc.postImmediate(ass, AD_Table_ID, Record_ID, force, trxName);
|
||||
} // postImmediate
|
||||
|
||||
/*************************************************************************
|
||||
* Get Prepared Statement ResultSet
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param info Result info
|
||||
* @return RowSet
|
||||
* @throws NotSerializableException
|
||||
*/
|
||||
public RowSet pstmt_getRowSet (CStatementVO info)
|
||||
throws NotSerializableException
|
||||
{
|
||||
log.finer("[" + m_no + "]");
|
||||
m_stmt_rowSetCount++;
|
||||
CPreparedStatement pstmt = new CPreparedStatement(info);
|
||||
return pstmt.remote_getRowSet();
|
||||
} // pstmt_getRowSet
|
||||
|
||||
/**
|
||||
* Get Statement ResultSet
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param info Result info
|
||||
* @return RowSet
|
||||
*/
|
||||
public RowSet stmt_getRowSet (CStatementVO info)
|
||||
{
|
||||
log.finer("[" + m_no + "]");
|
||||
m_stmt_rowSetCount++;
|
||||
CStatement stmt = new CStatement(info);
|
||||
return stmt.remote_getRowSet();
|
||||
} // stmt_getRowSet
|
||||
|
||||
/**
|
||||
* Execute Update
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param info Result info
|
||||
* @return row count
|
||||
*/
|
||||
public int stmt_executeUpdate (CStatementVO info)
|
||||
{
|
||||
log.finer("[" + m_no + "]");
|
||||
m_stmt_updateCount++;
|
||||
if (info.getParameterCount() == 0)
|
||||
{
|
||||
CStatement stmt = new CStatement(info);
|
||||
return stmt.remote_executeUpdate();
|
||||
}
|
||||
CPreparedStatement pstmt = new CPreparedStatement(info);
|
||||
return pstmt.remote_executeUpdate();
|
||||
} // stmt_executeUpdate
|
||||
|
||||
/*************************************************************************
|
||||
* Get next number for Key column = 0 is Error.
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param AD_Client_ID client
|
||||
* @param TableName table name
|
||||
* @param trxName optional Transaction Name
|
||||
* @return next no
|
||||
*/
|
||||
public int getNextID (int AD_Client_ID, String TableName, String trxName)
|
||||
{
|
||||
int retValue = MSequence.getNextID (AD_Client_ID, TableName, trxName);
|
||||
log.finer("[" + m_no + "] " + TableName + " = " + retValue);
|
||||
m_nextSeqCount++;
|
||||
return retValue;
|
||||
} // getNextID
|
||||
|
||||
/**
|
||||
* Get Document No from table
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param AD_Client_ID client
|
||||
* @param TableName table name
|
||||
* @param trxName optional Transaction Name
|
||||
* @return document no or null
|
||||
*/
|
||||
public String getDocumentNo (int AD_Client_ID, String TableName, String trxName)
|
||||
{
|
||||
m_nextSeqCount++;
|
||||
String dn = MSequence.getDocumentNo (AD_Client_ID, TableName, trxName);
|
||||
if (dn == null) // try again
|
||||
dn = MSequence.getDocumentNo (AD_Client_ID, TableName, trxName);
|
||||
return dn;
|
||||
} // GetDocumentNo
|
||||
|
||||
/**
|
||||
* Get Document No based on Document Type
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param C_DocType_ID document type
|
||||
* @param trxName optional Transaction Name
|
||||
* @return document no or null
|
||||
*/
|
||||
public String getDocumentNo (int C_DocType_ID, String trxName)
|
||||
{
|
||||
m_nextSeqCount++;
|
||||
String dn = MSequence.getDocumentNo (C_DocType_ID, trxName);
|
||||
if (dn == null) // try again
|
||||
dn = MSequence.getDocumentNo (C_DocType_ID, trxName);
|
||||
return dn;
|
||||
} // getDocumentNo
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Process Remote
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param ctx Context
|
||||
* @param pi Process Info
|
||||
* @return resulting Process Info
|
||||
*/
|
||||
public ProcessInfo process (Properties ctx, ProcessInfo pi)
|
||||
{
|
||||
String className = pi.getClassName();
|
||||
log.info(className + " - " + pi);
|
||||
m_processCount++;
|
||||
// Get Class
|
||||
Class clazz = null;
|
||||
try
|
||||
{
|
||||
clazz = Class.forName (className);
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
log.log(Level.WARNING, className, ex);
|
||||
pi.setSummary ("ClassNotFound", true);
|
||||
return pi;
|
||||
}
|
||||
// Get Process
|
||||
SvrProcess process = null;
|
||||
try
|
||||
{
|
||||
process = (SvrProcess)clazz.newInstance ();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.log(Level.WARNING, "Instance for " + className, ex);
|
||||
pi.setSummary ("InstanceError", true);
|
||||
return pi;
|
||||
}
|
||||
// Start Process
|
||||
Trx trx = Trx.get(Trx.createTrxName("ServerPrc"), true);
|
||||
try
|
||||
{
|
||||
boolean ok = process.startProcess (ctx, pi, trx);
|
||||
pi = process.getProcessInfo();
|
||||
trx.commit();
|
||||
trx.close();
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
trx.rollback();
|
||||
trx.close();
|
||||
pi.setSummary ("ProcessError", true);
|
||||
return pi;
|
||||
}
|
||||
return pi;
|
||||
} // process
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Run Workflow (and wait) on Server
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param ctx Context
|
||||
* @param pi Process Info
|
||||
* @param AD_Workflow_ID id
|
||||
* @return process info
|
||||
*/
|
||||
public ProcessInfo workflow (Properties ctx, ProcessInfo pi, int AD_Workflow_ID)
|
||||
{
|
||||
log.info ("[" + m_no + "] " + AD_Workflow_ID);
|
||||
m_workflowCount++;
|
||||
MWorkflow wf = MWorkflow.get (ctx, AD_Workflow_ID);
|
||||
MWFProcess wfProcess = null;
|
||||
if (pi.isBatch())
|
||||
wfProcess = wf.start(pi); // may return null
|
||||
else
|
||||
wfProcess = wf.startWait(pi); // may return null
|
||||
log.fine(pi.toString());
|
||||
return pi;
|
||||
} // workflow
|
||||
|
||||
/**
|
||||
* Online Payment from Server
|
||||
* @ejb.interface-method view-type="both"
|
||||
* Called from MPayment processOnline
|
||||
* @param ctx Context
|
||||
* @param C_Payment_ID payment
|
||||
* @param C_PaymentProcessor_ID processor
|
||||
* @param trxName transaction
|
||||
* @return true if approved
|
||||
*/
|
||||
public boolean paymentOnline (Properties ctx,
|
||||
int C_Payment_ID, int C_PaymentProcessor_ID, String trxName)
|
||||
{
|
||||
MPayment payment = new MPayment (ctx, C_Payment_ID, trxName);
|
||||
MPaymentProcessor mpp = new MPaymentProcessor (ctx, C_PaymentProcessor_ID, null);
|
||||
log.info ("[" + m_no + "] " + payment + " - " + mpp);
|
||||
m_paymentCount++;
|
||||
boolean approved = false;
|
||||
try
|
||||
{
|
||||
PaymentProcessor pp = PaymentProcessor.create(mpp, payment);
|
||||
if (pp == null)
|
||||
payment.setErrorMessage("No Payment Processor");
|
||||
else
|
||||
{
|
||||
approved = pp.processCC ();
|
||||
if (approved)
|
||||
payment.setErrorMessage(null);
|
||||
else
|
||||
payment.setErrorMessage("From " + payment.getCreditCardName()
|
||||
+ ": " + payment.getR_RespMsg());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "", e);
|
||||
payment.setErrorMessage("Payment Processor Error");
|
||||
}
|
||||
payment.save();
|
||||
return approved;
|
||||
} // paymentOnline
|
||||
|
||||
/**
|
||||
* Create EMail from Server (Request User)
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @param ctx Context
|
||||
* @param AD_Client_ID client
|
||||
* @param to recipient email address
|
||||
* @param subject subject
|
||||
* @param message message
|
||||
* @return EMail
|
||||
*/
|
||||
public EMail createEMail (Properties ctx, int AD_Client_ID,
|
||||
String to, String subject, String message)
|
||||
{
|
||||
MClient client = MClient.get(ctx, AD_Client_ID);
|
||||
return client.createEMail(to, subject, message);
|
||||
} // createEMail
|
||||
|
||||
/**
|
||||
* Create EMail from Server (Request User)
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @param ctx Context
|
||||
* @param AD_Client_ID client
|
||||
* @param AD_User_ID user to send email from
|
||||
* @param to recipient email address
|
||||
* @param subject subject
|
||||
* @param message message
|
||||
* @return EMail
|
||||
*/
|
||||
public EMail createEMail (Properties ctx, int AD_Client_ID,
|
||||
int AD_User_ID,
|
||||
String to, String subject, String message)
|
||||
{
|
||||
MClient client = MClient.get(ctx, AD_Client_ID);
|
||||
MUser from = new MUser (ctx, AD_User_ID, null);
|
||||
return client.createEMail(from, to, subject, message);
|
||||
} // createEMail
|
||||
|
||||
|
||||
/**
|
||||
* Create EMail from Server (Request User)
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @param AD_Task_ID task
|
||||
* @return execution trace
|
||||
*/
|
||||
public String executeTask (int AD_Task_ID)
|
||||
{
|
||||
MTask task = new MTask (Env.getCtx(), AD_Task_ID, null); // Server Context
|
||||
return task.execute();
|
||||
} // executeTask
|
||||
|
||||
|
||||
/**
|
||||
* Cash Reset
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param tableName table name
|
||||
* @param Record_ID record or 0 for all
|
||||
* @return number of records reset
|
||||
*/
|
||||
public int cacheReset (String tableName, int Record_ID)
|
||||
{
|
||||
log.config(tableName + " - " + Record_ID);
|
||||
m_cacheResetCount++;
|
||||
return CacheMgt.get().reset(tableName, Record_ID);
|
||||
} // cacheReset
|
||||
|
||||
/**
|
||||
* LOB update
|
||||
* @ejb.interface-method view-type="both"
|
||||
*
|
||||
* @param sql table name
|
||||
* @param displayType display type (i.e. BLOB/CLOB)
|
||||
* @param value the data
|
||||
* @return true if updated
|
||||
*/
|
||||
public boolean updateLOB (String sql, int displayType, Object value)
|
||||
{
|
||||
if (sql == null || value == null)
|
||||
{
|
||||
log.fine("No sql or data");
|
||||
return false;
|
||||
}
|
||||
log.fine(sql);
|
||||
m_updateLOBCount++;
|
||||
boolean success = true;
|
||||
Connection con = DB.createConnection(false, Connection.TRANSACTION_READ_COMMITTED);
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = con.prepareStatement(sql);
|
||||
if (displayType == DisplayType.TextLong)
|
||||
pstmt.setString(1, (String)value);
|
||||
else
|
||||
pstmt.setBytes(1, (byte[])value);
|
||||
int no = pstmt.executeUpdate();
|
||||
//
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.FINE, sql, e);
|
||||
success = false;
|
||||
}
|
||||
// Close Statement
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
// Success - commit local trx
|
||||
if (success)
|
||||
{
|
||||
try
|
||||
{
|
||||
con.commit();
|
||||
con.close();
|
||||
con = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "commit" , e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
// Error - roll back
|
||||
if (!success)
|
||||
{
|
||||
log.severe ("rollback");
|
||||
try
|
||||
{
|
||||
con.rollback();
|
||||
con.close();
|
||||
con = null;
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
log.log(Level.SEVERE, "rollback" , ee);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean Connection
|
||||
try
|
||||
{
|
||||
if (con != null)
|
||||
con.close();
|
||||
con = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
con = null;
|
||||
}
|
||||
return success;
|
||||
} // updateLOB
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Describes the instance and its content for debugging purpose
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Debugging information about the instance and its content
|
||||
*/
|
||||
public String getStatus()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("ServerBean[");
|
||||
sb.append(m_no)
|
||||
.append("-Window=").append(m_windowCount)
|
||||
.append(",Post=").append(m_postCount)
|
||||
.append(",Process=").append(m_processCount)
|
||||
.append(",NextSeq=").append(m_nextSeqCount)
|
||||
.append(",Workflow=").append(m_workflowCount)
|
||||
.append(",Payment=").append(m_paymentCount)
|
||||
.append(",RowSet=").append(m_stmt_rowSetCount)
|
||||
.append(",Update=").append(m_stmt_updateCount)
|
||||
.append(",CacheReset=").append(m_cacheResetCount)
|
||||
.append(",UpdateLob=").append(m_updateLOBCount)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
} // getStatus
|
||||
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getStatus();
|
||||
} // toString
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Create the Session Bean
|
||||
* @throws EJBException
|
||||
* @throws CreateException
|
||||
* @ejb.create-method view-type="both"
|
||||
*/
|
||||
public void ejbCreate() throws EJBException, CreateException
|
||||
{
|
||||
m_no = ++s_no;
|
||||
try
|
||||
{
|
||||
Adempiere.startup(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.log(Level.SEVERE, "ejbCreate", ex);
|
||||
// throw new CreateException ();
|
||||
}
|
||||
log.info ("#" + getStatus());
|
||||
} // ejbCreate
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Framework Callbacks
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method setSessionContext
|
||||
* @param aContext SessionContext
|
||||
* @throws EJBException
|
||||
* @see javax.ejb.SessionBean#setSessionContext(SessionContext)
|
||||
*/
|
||||
public void setSessionContext (SessionContext aContext) throws EJBException
|
||||
{
|
||||
m_Context = aContext;
|
||||
} // setSessionContext
|
||||
|
||||
/**
|
||||
* Method ejbActivate
|
||||
* @throws EJBException
|
||||
* @see javax.ejb.SessionBean#ejbActivate()
|
||||
*/
|
||||
public void ejbActivate() throws EJBException
|
||||
{
|
||||
if (log == null)
|
||||
log = CLogger.getCLogger(getClass());
|
||||
log.info ("ejbActivate " + getStatus());
|
||||
} // ejbActivate
|
||||
|
||||
/**
|
||||
* Method ejbPassivate
|
||||
* @throws EJBException
|
||||
* @see javax.ejb.SessionBean#ejbPassivate()
|
||||
*/
|
||||
public void ejbPassivate() throws EJBException
|
||||
{
|
||||
log.info ("ejbPassivate " + getStatus());
|
||||
} // ejbPassivate
|
||||
|
||||
/**
|
||||
* Method ejbRemove
|
||||
* @throws EJBException
|
||||
* @see javax.ejb.SessionBean#ejbRemove()
|
||||
*/
|
||||
public void ejbRemove() throws EJBException
|
||||
{
|
||||
log.info ("ejbRemove " + getStatus());
|
||||
} // ejbRemove
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Dump SerialVersionUID of class
|
||||
* @param clazz class
|
||||
*/
|
||||
protected static void dumpSVUID (Class clazz)
|
||||
{
|
||||
String s = clazz.getName()
|
||||
+ " ==\nstatic final long serialVersionUID = "
|
||||
+ java.io.ObjectStreamClass.lookup(clazz).getSerialVersionUID()
|
||||
+ "L;\n";
|
||||
System.out.println (s);
|
||||
} // dumpSVUID
|
||||
|
||||
/**
|
||||
* Print UID of used classes.
|
||||
* R2.5.1h
|
||||
|
||||
org.compiere.process.ProcessInfo ==
|
||||
static final long serialVersionUID = -1993220053515488725L;
|
||||
|
||||
org.compiere.util.CStatementVO ==
|
||||
static final long serialVersionUID = -3393389471515956399L;
|
||||
|
||||
org.compiere.model.MQuery ==
|
||||
static final long serialVersionUID = 1511402030597166113L;
|
||||
|
||||
org.compiere.model.POInfo ==
|
||||
static final long serialVersionUID = -5976719579744948419L;
|
||||
|
||||
org.compiere.model.POInfoColumn ==
|
||||
static final long serialVersionUID = -3983585608504631958L;
|
||||
|
||||
org.compiere.model.MWindowVO ==
|
||||
static final long serialVersionUID = 3802628212531678981L;
|
||||
|
||||
org.compiere.model.MTabVO ==
|
||||
static final long serialVersionUID = 9160212869277319305L;
|
||||
|
||||
org.compiere.model.MFieldVO ==
|
||||
static final long serialVersionUID = 4385061125114436797L;
|
||||
|
||||
org.compiere.model.MLookupInfo ==
|
||||
static final long serialVersionUID = -7958664359250070233L;
|
||||
|
||||
*
|
||||
* * @param args ignored
|
||||
*/
|
||||
public static void main (String[] args)
|
||||
{
|
||||
dumpSVUID(ProcessInfo.class);
|
||||
dumpSVUID(CStatementVO.class);
|
||||
dumpSVUID(MQuery.class);
|
||||
dumpSVUID(POInfo.class);
|
||||
dumpSVUID(POInfoColumn.class);
|
||||
dumpSVUID(GridWindowVO.class);
|
||||
dumpSVUID(GridTabVO.class);
|
||||
dumpSVUID(GridFieldVO.class);
|
||||
dumpSVUID(MLookupInfo.class);
|
||||
} // main
|
||||
|
||||
} // ServerBean
|
|
@ -0,0 +1,288 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.session;
|
||||
|
||||
import java.util.logging.*;
|
||||
import javax.ejb.*;
|
||||
|
||||
import org.compiere.*;
|
||||
import org.compiere.db.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Adempiere Status Bean
|
||||
*
|
||||
* @ejb.bean name="adempiere/Status"
|
||||
* display-name="Adempiere Status Session Bean"
|
||||
* type="Stateless"
|
||||
* view-type="both"
|
||||
* transaction-type="Bean"
|
||||
* jndi-name="adempiere/Status"
|
||||
* local-jndi-name="adempiere/StatusLocal"
|
||||
*
|
||||
* @ejb.ejb-ref ejb-name="adempiere/Status"
|
||||
* view-type="both"
|
||||
* ref-name="adempiere/Status"
|
||||
* @ejb.ejb-ref ejb-name="adempiere/Status"
|
||||
* view-type="local"
|
||||
* ref-name="adempiere/StatusLocal"
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: StatusBean.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class StatusBean implements SessionBean
|
||||
{
|
||||
/** Context */
|
||||
private SessionContext m_Context;
|
||||
/** Logging */
|
||||
private static CLogger log = CLogger.getCLogger(StatusBean.class);
|
||||
|
||||
private static int s_no = 0;
|
||||
private int m_no = 0;
|
||||
//
|
||||
private int m_versionCount = 0;
|
||||
private int m_databaseCount = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Get Version (Date)
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return version e.g. 2002-09-02
|
||||
*/
|
||||
public String getDateVersion()
|
||||
{
|
||||
m_versionCount++;
|
||||
log.info ("getDateVersion " + m_versionCount);
|
||||
return Adempiere.DATE_VERSION;
|
||||
} // getDateVersion
|
||||
|
||||
/**
|
||||
* Get Main Version
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return main version - e.g. Version 2.4.3b
|
||||
*/
|
||||
public String getMainVersion()
|
||||
{
|
||||
return Adempiere.MAIN_VERSION;
|
||||
} // getMainVersion
|
||||
|
||||
/**
|
||||
* Get Database Type
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database Type
|
||||
*/
|
||||
public String getDbType()
|
||||
{
|
||||
return CConnection.get().getType();
|
||||
} // getDbType
|
||||
|
||||
/**
|
||||
* Get Database Host
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database Host Name
|
||||
*/
|
||||
public String getDbHost()
|
||||
{
|
||||
m_databaseCount++;
|
||||
log.info ("getDbHost " + m_databaseCount);
|
||||
return CConnection.get().getDbHost();
|
||||
} // getDbHost
|
||||
|
||||
/**
|
||||
* Get Database Port
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database Port
|
||||
*/
|
||||
public int getDbPort()
|
||||
{
|
||||
return CConnection.get().getDbPort();
|
||||
} // getDbPort
|
||||
|
||||
/**
|
||||
* Get Database SID
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database SID
|
||||
*/
|
||||
public String getDbName()
|
||||
{
|
||||
return CConnection.get().getDbName();
|
||||
} // getDbSID
|
||||
|
||||
/**
|
||||
* Get Database URL
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database URL
|
||||
*/
|
||||
public String getConnectionURL()
|
||||
{
|
||||
return CConnection.get().getConnectionURL();
|
||||
} // getConnectionURL
|
||||
|
||||
/**
|
||||
* Get Database UID
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database User Name
|
||||
*/
|
||||
public String getDbUid()
|
||||
{
|
||||
return CConnection.get().getDbUid();
|
||||
} // getDbUID
|
||||
|
||||
/**
|
||||
* Get Database PWD
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Database User Password
|
||||
*/
|
||||
public String getDbPwd()
|
||||
{
|
||||
return CConnection.get().getDbPwd();
|
||||
} // getDbPWD
|
||||
|
||||
/**
|
||||
* Get Connection Manager Host
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Connection Manager Host
|
||||
*/
|
||||
public String getFwHost()
|
||||
{
|
||||
return CConnection.get().getFwHost();
|
||||
} // getCMHost
|
||||
|
||||
/**
|
||||
* Get Connection Manager Port
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Connection Manager Port
|
||||
*/
|
||||
public int getFwPort()
|
||||
{
|
||||
return CConnection.get().getFwPort();
|
||||
} // getCMPort
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Version Count
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return number of version inquiries
|
||||
*/
|
||||
public int getVersionCount()
|
||||
{
|
||||
return m_versionCount;
|
||||
} // getVersionCount
|
||||
|
||||
/**
|
||||
* Get Database Count
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return number of database inquiries
|
||||
*/
|
||||
public int getDatabaseCount()
|
||||
{
|
||||
return m_databaseCount;
|
||||
} // getVersionCount
|
||||
|
||||
/**
|
||||
* Describes the instance and its content for debugging purpose
|
||||
* @ejb.interface-method view-type="both"
|
||||
* @return Debugging information about the instance and its content
|
||||
*/
|
||||
public String getStatus()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("StatusBean[No=");
|
||||
sb.append(m_no)
|
||||
.append(",VersionCount=").append(m_versionCount)
|
||||
.append(",DatabaseCount=").append(m_versionCount)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
} // getStatus
|
||||
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getStatus();
|
||||
} // toString
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Create the Session Bean
|
||||
* @throws EJBException
|
||||
* @throws CreateException
|
||||
* @ejb.create-method view-type="both"
|
||||
*/
|
||||
public void ejbCreate() throws EJBException, CreateException
|
||||
{
|
||||
m_no = ++s_no;
|
||||
try
|
||||
{
|
||||
org.compiere.Adempiere.startup(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.log(Level.SEVERE, "", ex);
|
||||
// throw new CreateException ();
|
||||
}
|
||||
log.info("#" + m_no + " - " + getStatus());
|
||||
} // ejbCreate
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Framework Callbacks
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set Session Context
|
||||
* @param aContext context
|
||||
* @throws EJBException
|
||||
*/
|
||||
public void setSessionContext (SessionContext aContext) throws EJBException
|
||||
{
|
||||
m_Context = aContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejb Activate
|
||||
* @throws EJBException
|
||||
*/
|
||||
public void ejbActivate() throws EJBException
|
||||
{
|
||||
if (log == null)
|
||||
log = CLogger.getCLogger(getClass());
|
||||
log.fine("ejbActivate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejb Passivate
|
||||
* @throws EJBException
|
||||
*/
|
||||
public void ejbPassivate() throws EJBException
|
||||
{
|
||||
log.fine("ejbPassivate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejb Remove
|
||||
* @throws EJBException
|
||||
*/
|
||||
public void ejbRemove() throws EJBException
|
||||
{
|
||||
log.fine("ejbRemove");
|
||||
}
|
||||
|
||||
} // StatusBean
|
|
@ -0,0 +1,142 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Allocation Line
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: DocLine_Allocation.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class DocLine_Allocation extends DocLine
|
||||
{
|
||||
/**
|
||||
* DocLine_Allocation
|
||||
* @param line allocation line
|
||||
* @param doc header
|
||||
*/
|
||||
public DocLine_Allocation (MAllocationLine line, Doc doc)
|
||||
{
|
||||
super (line, doc);
|
||||
m_C_Payment_ID = line.getC_Payment_ID();
|
||||
m_C_CashLine_ID = line.getC_CashLine_ID();
|
||||
m_C_Invoice_ID = line.getC_Invoice_ID();
|
||||
m_C_Order_ID = line.getC_Order_ID();
|
||||
//
|
||||
setAmount(line.getAmount());
|
||||
m_DiscountAmt = line.getDiscountAmt();
|
||||
m_WriteOffAmt = line.getWriteOffAmt();
|
||||
m_OverUnderAmt = line.getOverUnderAmt();
|
||||
} // DocLine_Allocation
|
||||
|
||||
private int m_C_Invoice_ID;
|
||||
private int m_C_Payment_ID;
|
||||
private int m_C_CashLine_ID;
|
||||
private int m_C_Order_ID;
|
||||
private BigDecimal m_DiscountAmt;
|
||||
private BigDecimal m_WriteOffAmt;
|
||||
private BigDecimal m_OverUnderAmt;
|
||||
|
||||
|
||||
/**
|
||||
* Get Invoice C_Currency_ID
|
||||
* @return 0 if no invoice -1 if not found
|
||||
*/
|
||||
public int getInvoiceC_Currency_ID()
|
||||
{
|
||||
if (m_C_Invoice_ID == 0)
|
||||
return 0;
|
||||
String sql = "SELECT C_Currency_ID "
|
||||
+ "FROM C_Invoice "
|
||||
+ "WHERE C_Invoice_ID=?";
|
||||
return DB.getSQLValue(null, sql, m_C_Invoice_ID);
|
||||
} // getInvoiceC_Currency_ID
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ("DocLine_Allocation[");
|
||||
sb.append(get_ID())
|
||||
.append(",Amt=").append(getAmtSource())
|
||||
.append(",Discount=").append(getDiscountAmt())
|
||||
.append(",WriteOff=").append(getWriteOffAmt())
|
||||
.append(",OverUnderAmt=").append(getOverUnderAmt())
|
||||
.append(" - C_Payment_ID=").append(m_C_Payment_ID)
|
||||
.append(",C_CashLine_ID=").append(m_C_CashLine_ID)
|
||||
.append(",C_Invoice_ID=").append(m_C_Invoice_ID)
|
||||
.append("]");
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the c_Order_ID.
|
||||
*/
|
||||
public int getC_Order_ID ()
|
||||
{
|
||||
return m_C_Order_ID;
|
||||
}
|
||||
/**
|
||||
* @return Returns the discountAmt.
|
||||
*/
|
||||
public BigDecimal getDiscountAmt ()
|
||||
{
|
||||
return m_DiscountAmt;
|
||||
}
|
||||
/**
|
||||
* @return Returns the overUnderAmt.
|
||||
*/
|
||||
public BigDecimal getOverUnderAmt ()
|
||||
{
|
||||
return m_OverUnderAmt;
|
||||
}
|
||||
/**
|
||||
* @return Returns the writeOffAmt.
|
||||
*/
|
||||
public BigDecimal getWriteOffAmt ()
|
||||
{
|
||||
return m_WriteOffAmt;
|
||||
}
|
||||
/**
|
||||
* @return Returns the c_CashLine_ID.
|
||||
*/
|
||||
public int getC_CashLine_ID ()
|
||||
{
|
||||
return m_C_CashLine_ID;
|
||||
}
|
||||
/**
|
||||
* @return Returns the c_Invoice_ID.
|
||||
*/
|
||||
public int getC_Invoice_ID ()
|
||||
{
|
||||
return m_C_Invoice_ID;
|
||||
}
|
||||
/**
|
||||
* @return Returns the c_Payment_ID.
|
||||
*/
|
||||
public int getC_Payment_ID ()
|
||||
{
|
||||
return m_C_Payment_ID;
|
||||
}
|
||||
} // DocLine_Allocation
|
|
@ -0,0 +1,122 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
//import org.compiere.model.*;
|
||||
|
||||
/**
|
||||
* Bank Statement Line
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: DocLine_Bank.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class DocLine_Bank extends DocLine
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param line statement line
|
||||
* @param doc header
|
||||
*/
|
||||
public DocLine_Bank (MBankStatementLine line, Doc_Bank doc)
|
||||
{
|
||||
super (line, doc);
|
||||
m_C_Payment_ID = line.getC_Payment_ID();
|
||||
m_IsReversal = line.isReversal();
|
||||
//
|
||||
m_StmtAmt = line.getStmtAmt();
|
||||
m_InterestAmt = line.getInterestAmt();
|
||||
m_TrxAmt = line.getTrxAmt();
|
||||
//
|
||||
setDateDoc(line.getValutaDate());
|
||||
setC_BPartner_ID(line.getC_BPartner_ID());
|
||||
} // DocLine_Bank
|
||||
|
||||
/** Reversal Flag */
|
||||
private boolean m_IsReversal = false;
|
||||
/** Payment */
|
||||
private int m_C_Payment_ID = 0;
|
||||
|
||||
private BigDecimal m_TrxAmt = Env.ZERO;
|
||||
private BigDecimal m_StmtAmt = Env.ZERO;
|
||||
private BigDecimal m_InterestAmt = Env.ZERO;
|
||||
|
||||
/**
|
||||
* Get Payment
|
||||
* @return C_Paymnet_ID
|
||||
*/
|
||||
public int getC_Payment_ID()
|
||||
{
|
||||
return m_C_Payment_ID;
|
||||
} // getC_Payment_ID
|
||||
|
||||
/**
|
||||
* Get AD_Org_ID
|
||||
* @param payment if true get Org from payment
|
||||
* @return org
|
||||
*/
|
||||
public int getAD_Org_ID (boolean payment)
|
||||
{
|
||||
if (payment && getC_Payment_ID() != 0)
|
||||
{
|
||||
String sql = "SELECT AD_Org_ID FROM C_Payment WHERE C_Payment_ID=?";
|
||||
int id = DB.getSQLValue(null, sql, getC_Payment_ID());
|
||||
if (id > 0)
|
||||
return id;
|
||||
}
|
||||
return super.getAD_Org_ID();
|
||||
} // getAD_Org_ID
|
||||
|
||||
/**
|
||||
* Is Reversal
|
||||
* @return true if reversal
|
||||
*/
|
||||
public boolean isReversal()
|
||||
{
|
||||
return m_IsReversal;
|
||||
} // isReversal
|
||||
|
||||
/**
|
||||
* Get Interest
|
||||
* @return InterestAmount
|
||||
*/
|
||||
public BigDecimal getInterestAmt()
|
||||
{
|
||||
return m_InterestAmt;
|
||||
} // getInterestAmt
|
||||
|
||||
/**
|
||||
* Get Statement
|
||||
* @return Starement Amount
|
||||
*/
|
||||
public BigDecimal getStmtAmt()
|
||||
{
|
||||
return m_StmtAmt;
|
||||
} // getStrmtAmt
|
||||
|
||||
/**
|
||||
* Get Transaction
|
||||
* @return transaction amount
|
||||
*/
|
||||
public BigDecimal getTrxAmt()
|
||||
{
|
||||
return m_TrxAmt;
|
||||
} // getTrxAmt
|
||||
|
||||
} // DocLine_Bank
|
|
@ -0,0 +1,138 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Cash Journal Line
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: DocLine_Cash.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class DocLine_Cash extends DocLine
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param line cash line
|
||||
* @param doc header
|
||||
*/
|
||||
public DocLine_Cash (MCashLine line, Doc_Cash doc)
|
||||
{
|
||||
super (line, doc);
|
||||
m_CashType = line.getCashType();
|
||||
m_C_BankAccount_ID = line.getC_BankAccount_ID();
|
||||
m_C_Invoice_ID = line.getC_Invoice_ID();
|
||||
//
|
||||
if (m_C_Invoice_ID != 0)
|
||||
{
|
||||
MInvoice invoice = MInvoice.get(line.getCtx(), m_C_Invoice_ID);
|
||||
setC_BPartner_ID(invoice.getC_BPartner_ID());
|
||||
}
|
||||
|
||||
//
|
||||
m_Amount = line.getAmount();
|
||||
m_DiscountAmt = line.getDiscountAmt();
|
||||
m_WriteOffAmt = line.getWriteOffAmt();
|
||||
setAmount(m_Amount);
|
||||
|
||||
|
||||
} // DocLine_Cash
|
||||
|
||||
/** Cash Type */
|
||||
private String m_CashType = "";
|
||||
|
||||
// AD_Reference_ID=217
|
||||
/** Charge - C */
|
||||
public static final String CASHTYPE_CHARGE = "C";
|
||||
/** Difference - D */
|
||||
public static final String CASHTYPE_DIFFERENCE = "D";
|
||||
/** Expense - E */
|
||||
public static final String CASHTYPE_EXPENSE = "E";
|
||||
/** Onvoice - I */
|
||||
public static final String CASHTYPE_INVOICE = "I";
|
||||
/** Receipt - R */
|
||||
public static final String CASHTYPE_RECEIPT = "R";
|
||||
/** Transfer - T */
|
||||
public static final String CASHTYPE_TRANSFER = "T";
|
||||
|
||||
// References
|
||||
private int m_C_BankAccount_ID = 0;
|
||||
private int m_C_Invoice_ID = 0;
|
||||
|
||||
// Amounts
|
||||
private BigDecimal m_Amount = Env.ZERO;
|
||||
private BigDecimal m_DiscountAmt = Env.ZERO;
|
||||
private BigDecimal m_WriteOffAmt = Env.ZERO;
|
||||
|
||||
|
||||
/**
|
||||
* Get Cash Type
|
||||
* @return cash type
|
||||
*/
|
||||
public String getCashType()
|
||||
{
|
||||
return m_CashType;
|
||||
} // getCashType
|
||||
|
||||
/**
|
||||
* Get Bank Account
|
||||
* @return Bank Account
|
||||
*/
|
||||
public int getC_BankAccount_ID()
|
||||
{
|
||||
return m_C_BankAccount_ID;
|
||||
} // getC_BankAccount_ID
|
||||
|
||||
/**
|
||||
* Get Invoice
|
||||
* @return C_Invoice_ID
|
||||
*/
|
||||
public int getC_Invoice_ID()
|
||||
{
|
||||
return m_C_Invoice_ID;
|
||||
} // getC_Invoice_ID
|
||||
|
||||
/**
|
||||
* Get Amount
|
||||
* @return Payment Amount
|
||||
*/
|
||||
public BigDecimal getAmount()
|
||||
{
|
||||
return m_Amount;
|
||||
}
|
||||
/**
|
||||
* Get Discount
|
||||
* @return Discount Amount
|
||||
*/
|
||||
public BigDecimal getDiscountAmt()
|
||||
{
|
||||
return m_DiscountAmt;
|
||||
}
|
||||
/**
|
||||
* Get WriteOff
|
||||
* @return Write-Off Amount
|
||||
*/
|
||||
public BigDecimal getWriteOffAmt()
|
||||
{
|
||||
return m_WriteOffAmt;
|
||||
}
|
||||
|
||||
} // DocLine_Cash
|
|
@ -0,0 +1,240 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import org.compiere.model.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Document Tax Line
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: DocTax.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public final class DocTax
|
||||
{
|
||||
/**
|
||||
* Create Tax
|
||||
* @param C_Tax_ID tax
|
||||
* @param name name
|
||||
* @param rate rate
|
||||
* @param taxBaseAmt tax base amount
|
||||
* @param amount amount
|
||||
* @param salesTax sales tax flag
|
||||
*/
|
||||
public DocTax (int C_Tax_ID, String name, BigDecimal rate,
|
||||
BigDecimal taxBaseAmt, BigDecimal amount, boolean salesTax)
|
||||
{
|
||||
m_C_Tax_ID = C_Tax_ID;
|
||||
m_name = name;
|
||||
m_rate = rate;
|
||||
m_amount = amount;
|
||||
m_salesTax = salesTax;
|
||||
} // DocTax
|
||||
|
||||
/** Tax ID */
|
||||
private int m_C_Tax_ID = 0;
|
||||
/** Amount */
|
||||
private BigDecimal m_amount = null;
|
||||
/** Tax Rate */
|
||||
private BigDecimal m_rate = null;
|
||||
/** Name */
|
||||
private String m_name = null;
|
||||
/** Base Tax Amt */
|
||||
private BigDecimal m_taxBaseAmt = null;
|
||||
/** Included Tax */
|
||||
private BigDecimal m_includedTax = Env.ZERO;
|
||||
/** Sales Tax */
|
||||
private boolean m_salesTax = false;
|
||||
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger(DocTax.class);
|
||||
|
||||
|
||||
/** Tax Due Acct */
|
||||
public static final int ACCTTYPE_TaxDue = 0;
|
||||
/** Tax Liability */
|
||||
public static final int ACCTTYPE_TaxLiability = 1;
|
||||
/** Tax Credit */
|
||||
public static final int ACCTTYPE_TaxCredit = 2;
|
||||
/** Tax Receivables */
|
||||
public static final int ACCTTYPE_TaxReceivables = 3;
|
||||
/** Tax Expense */
|
||||
public static final int ACCTTYPE_TaxExpense = 4;
|
||||
|
||||
/**
|
||||
* Get Account
|
||||
* @param AcctType see ACCTTYPE_*
|
||||
* @param as account schema
|
||||
* @return Account
|
||||
*/
|
||||
public MAccount getAccount (int AcctType, MAcctSchema as)
|
||||
{
|
||||
if (AcctType < 0 || AcctType > 4)
|
||||
return null;
|
||||
//
|
||||
String sql = "SELECT T_Due_Acct, T_Liability_Acct, T_Credit_Acct, T_Receivables_Acct, T_Expense_Acct "
|
||||
+ "FROM C_Tax_Acct WHERE C_Tax_ID=? AND C_AcctSchema_ID=?";
|
||||
int validCombination_ID = 0;
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_C_Tax_ID);
|
||||
pstmt.setInt(2, as.getC_AcctSchema_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
validCombination_ID = rs.getInt(AcctType+1); // 1..5
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
if (validCombination_ID == 0)
|
||||
return null;
|
||||
return MAccount.get(as.getCtx(), validCombination_ID);
|
||||
} // getAccount
|
||||
|
||||
/**
|
||||
* Get Amount
|
||||
* @return gross amount
|
||||
*/
|
||||
public BigDecimal getAmount()
|
||||
{
|
||||
return m_amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Base Amount
|
||||
* @return net amount
|
||||
*/
|
||||
public BigDecimal getTaxBaseAmt()
|
||||
{
|
||||
return m_taxBaseAmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rate
|
||||
* @return tax rate in percent
|
||||
*/
|
||||
public BigDecimal getRate()
|
||||
{
|
||||
return m_rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name of Tax
|
||||
* @return name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get C_Tax_ID
|
||||
* @return tax id
|
||||
*/
|
||||
public int getC_Tax_ID()
|
||||
{
|
||||
return m_C_Tax_ID;
|
||||
} // getC_Tax_ID
|
||||
|
||||
/**
|
||||
* Get Description (Tax Name and Base Amount)
|
||||
* @return tax anme and base amount
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return m_name + " " + m_taxBaseAmt.toString();
|
||||
} // getDescription
|
||||
|
||||
/**
|
||||
* Add to Included Tax
|
||||
* @param amt amount
|
||||
*/
|
||||
public void addIncludedTax (BigDecimal amt)
|
||||
{
|
||||
m_includedTax = m_includedTax.add(amt);
|
||||
} // addIncludedTax
|
||||
|
||||
/**
|
||||
* Get Included Tax
|
||||
* @return tax amount
|
||||
*/
|
||||
public BigDecimal getIncludedTax()
|
||||
{
|
||||
return m_includedTax;
|
||||
} // getIncludedTax
|
||||
|
||||
/**
|
||||
* Get Included Tax Difference
|
||||
* @return tax ampunt - included amount
|
||||
*/
|
||||
public BigDecimal getIncludedTaxDifference()
|
||||
{
|
||||
return m_amount.subtract(m_includedTax);
|
||||
} // getIncludedTaxDifference
|
||||
|
||||
/**
|
||||
* Included Tax differs from tax amount
|
||||
* @return true if difference
|
||||
*/
|
||||
public boolean isIncludedTaxDifference()
|
||||
{
|
||||
return Env.ZERO.compareTo(getIncludedTaxDifference()) != 0;
|
||||
} // isIncludedTaxDifference
|
||||
|
||||
/**
|
||||
* Get AP Tax Type
|
||||
* @return AP tax type (Credit or Expense)
|
||||
*/
|
||||
public int getAPTaxType()
|
||||
{
|
||||
if (isSalesTax())
|
||||
return ACCTTYPE_TaxExpense;
|
||||
return ACCTTYPE_TaxCredit;
|
||||
} // getAPTaxAcctType
|
||||
|
||||
/**
|
||||
* Is Sales Tax
|
||||
* @return sales tax
|
||||
*/
|
||||
public boolean isSalesTax()
|
||||
{
|
||||
return m_salesTax;
|
||||
} // isSalesTax
|
||||
|
||||
|
||||
/**
|
||||
* Return String representation
|
||||
* @return tax anme and base amount
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("Tax=(");
|
||||
sb.append(m_name);
|
||||
sb.append(" Amt=").append(m_amount);
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
} // toString
|
||||
|
||||
} // DocTax
|
|
@ -0,0 +1,892 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.apache.taglibs.standard.lang.jstl.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Allocation Documents.
|
||||
* <pre>
|
||||
* Table: C_AllocationHdr
|
||||
* Document Types: CMA
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Allocation.java,v 1.6 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Allocation extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Allocation (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MAllocationHdr.class, rs, DOCTYPE_Allocation, trxName);
|
||||
} // Doc_Allocation
|
||||
|
||||
/** Tolearance G&L */
|
||||
private static final BigDecimal TOLERANCE = new BigDecimal (0.02);
|
||||
/** Facts */
|
||||
private ArrayList<Fact> m_facts = null;
|
||||
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MAllocationHdr alloc = (MAllocationHdr)getPO();
|
||||
setDateDoc(alloc.getDateTrx());
|
||||
// Contained Objects
|
||||
p_lines = loadLines(alloc);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param alloc header
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MAllocationHdr alloc)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MAllocationLine[] lines = alloc.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MAllocationLine line = lines[i];
|
||||
DocLine_Allocation docLine = new DocLine_Allocation(line, this);
|
||||
|
||||
// Get Payment Conversion Rate
|
||||
if (line.getC_Payment_ID() != 0)
|
||||
{
|
||||
MPayment payment = new MPayment (getCtx(), line.getC_Payment_ID(), getTrxName());
|
||||
int C_ConversionType_ID = payment.getC_ConversionType_ID();
|
||||
docLine.setC_ConversionType_ID(C_ConversionType_ID);
|
||||
}
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* CMA.
|
||||
* <pre>
|
||||
* AR_Invoice_Payment
|
||||
* UnAllocatedCash DR
|
||||
* or C_Prepayment
|
||||
* DiscountExp DR
|
||||
* WriteOff DR
|
||||
* Receivables CR
|
||||
* AR_Invoice_Cash
|
||||
* CashTransfer DR
|
||||
* DiscountExp DR
|
||||
* WriteOff DR
|
||||
* Receivables CR
|
||||
*
|
||||
* AP_Invoice_Payment
|
||||
* Liability DR
|
||||
* DiscountRev CR
|
||||
* WriteOff CR
|
||||
* PaymentSelect CR
|
||||
* or V_Prepayment
|
||||
* AP_Invoice_Cash
|
||||
* Liability DR
|
||||
* DiscountRev CR
|
||||
* WriteOff CR
|
||||
* CashTransfer CR
|
||||
* CashBankTransfer
|
||||
* -
|
||||
* ==============================
|
||||
* Realized Gain & Loss
|
||||
* AR/AP DR CR
|
||||
* Realized G/L DR CR
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* Tax needs to be corrected for discount & write-off;
|
||||
* Currency gain & loss is realized here.
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
m_facts = new ArrayList<Fact>();
|
||||
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine_Allocation line = (DocLine_Allocation)p_lines[i];
|
||||
setC_BPartner_ID(line.getC_BPartner_ID());
|
||||
|
||||
// CashBankTransfer - all references null and Discount/WriteOff = 0
|
||||
if (line.getC_Payment_ID() != 0
|
||||
&& line.getC_Invoice_ID() == 0 && line.getC_Order_ID() == 0
|
||||
&& line.getC_CashLine_ID() == 0 && line.getC_BPartner_ID() == 0
|
||||
&& Env.ZERO.compareTo(line.getDiscountAmt()) == 0
|
||||
&& Env.ZERO.compareTo(line.getWriteOffAmt()) == 0)
|
||||
continue;
|
||||
|
||||
// Receivables/Liability Amt
|
||||
BigDecimal allocationSource = line.getAmtSource()
|
||||
.add(line.getDiscountAmt())
|
||||
.add(line.getWriteOffAmt());
|
||||
BigDecimal allocationAccounted = null; // AR/AP balance corrected
|
||||
|
||||
FactLine fl = null;
|
||||
MAccount bpAcct = null; // Liability/Receivables
|
||||
//
|
||||
MPayment payment = null;
|
||||
if (line.getC_Payment_ID() != 0)
|
||||
payment = new MPayment (getCtx(), line.getC_Payment_ID(), getTrxName());
|
||||
MInvoice invoice = null;
|
||||
if (line.getC_Invoice_ID() != 0)
|
||||
invoice = new MInvoice (getCtx(), line.getC_Invoice_ID(), null);
|
||||
|
||||
// No Invoice
|
||||
if (invoice == null)
|
||||
{
|
||||
// Payment Only
|
||||
if (line.getC_Invoice_ID() == 0 && line.getC_Payment_ID() != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getPaymentAcct(as, line.getC_Payment_ID()),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
else
|
||||
{
|
||||
p_Error = "Cannot determine SO/PO";
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Sales Invoice
|
||||
else if (invoice.isSOTrx())
|
||||
{
|
||||
// Payment/Cash DR
|
||||
if (line.getC_Payment_ID() != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getPaymentAcct(as, line.getC_Payment_ID()),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
else if (line.getC_CashLine_ID() != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getCashAcct(as, line.getC_CashLine_ID()),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
MCashLine cashLine = new MCashLine (getCtx(), line.getC_CashLine_ID(), getTrxName());
|
||||
if (fl != null && cashLine.get_ID() != 0)
|
||||
fl.setAD_Org_ID(cashLine.getAD_Org_ID());
|
||||
}
|
||||
// Discount DR
|
||||
if (Env.ZERO.compareTo(line.getDiscountAmt()) != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getAccount(Doc.ACCTTYPE_DiscountExp, as),
|
||||
getC_Currency_ID(), line.getDiscountAmt(), null);
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
// Write off DR
|
||||
if (Env.ZERO.compareTo(line.getWriteOffAmt()) != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getAccount(Doc.ACCTTYPE_WriteOff, as),
|
||||
getC_Currency_ID(), line.getWriteOffAmt(), null);
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
|
||||
// AR Invoice Amount CR
|
||||
if (as.isAccrual())
|
||||
{
|
||||
bpAcct = getAccount(Doc.ACCTTYPE_C_Receivable, as);
|
||||
fl = fact.createLine (line, bpAcct,
|
||||
getC_Currency_ID(), null, allocationSource); // payment currency
|
||||
if (fl != null)
|
||||
allocationAccounted = fl.getAcctBalance().negate();
|
||||
if (fl != null && invoice != null)
|
||||
fl.setAD_Org_ID(invoice.getAD_Org_ID());
|
||||
}
|
||||
else // Cash Based
|
||||
{
|
||||
allocationAccounted = createCashBasedAcct (as, fact,
|
||||
invoice, allocationSource);
|
||||
}
|
||||
}
|
||||
// Purchase Invoice
|
||||
else
|
||||
{
|
||||
allocationSource = allocationSource.negate(); // allocation is negative
|
||||
// AP Invoice Amount DR
|
||||
if (as.isAccrual())
|
||||
{
|
||||
bpAcct = getAccount(Doc.ACCTTYPE_V_Liability, as);
|
||||
fl = fact.createLine (line, bpAcct,
|
||||
getC_Currency_ID(), allocationSource, null); // payment currency
|
||||
if (fl != null)
|
||||
allocationAccounted = fl.getAcctBalance();
|
||||
if (fl != null && invoice != null)
|
||||
fl.setAD_Org_ID(invoice.getAD_Org_ID());
|
||||
}
|
||||
else // Cash Based
|
||||
{
|
||||
allocationAccounted = createCashBasedAcct (as, fact,
|
||||
invoice, allocationSource);
|
||||
}
|
||||
|
||||
// Discount CR
|
||||
if (Env.ZERO.compareTo(line.getDiscountAmt()) != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getAccount(Doc.ACCTTYPE_DiscountRev, as),
|
||||
getC_Currency_ID(), null, line.getDiscountAmt().negate());
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
// Write off CR
|
||||
if (Env.ZERO.compareTo(line.getWriteOffAmt()) != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getAccount(Doc.ACCTTYPE_WriteOff, as),
|
||||
getC_Currency_ID(), null, line.getWriteOffAmt().negate());
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
// Payment/Cash CR
|
||||
if (line.getC_Payment_ID() != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getPaymentAcct(as, line.getC_Payment_ID()),
|
||||
getC_Currency_ID(), null, line.getAmtSource().negate());
|
||||
if (fl != null && payment != null)
|
||||
fl.setAD_Org_ID(payment.getAD_Org_ID());
|
||||
}
|
||||
else if (line.getC_CashLine_ID() != 0)
|
||||
{
|
||||
fl = fact.createLine (line, getCashAcct(as, line.getC_CashLine_ID()),
|
||||
getC_Currency_ID(), null, line.getAmtSource().negate());
|
||||
MCashLine cashLine = new MCashLine (getCtx(), line.getC_CashLine_ID(), getTrxName());
|
||||
if (fl != null && cashLine.get_ID() != 0)
|
||||
fl.setAD_Org_ID(cashLine.getAD_Org_ID());
|
||||
}
|
||||
}
|
||||
|
||||
// VAT Tax Correction
|
||||
if (invoice != null && as.isTaxCorrection())
|
||||
{
|
||||
BigDecimal taxCorrectionAmt = Env.ZERO;
|
||||
if (as.isTaxCorrectionDiscount())
|
||||
taxCorrectionAmt = line.getDiscountAmt();
|
||||
if (as.isTaxCorrectionWriteOff())
|
||||
taxCorrectionAmt = taxCorrectionAmt.add(line.getWriteOffAmt());
|
||||
//
|
||||
if (taxCorrectionAmt.signum() != 0)
|
||||
{
|
||||
if (!createTaxCorrection(as, fact, line,
|
||||
getAccount(invoice.isSOTrx() ? Doc.ACCTTYPE_DiscountExp : Doc.ACCTTYPE_DiscountRev, as),
|
||||
getAccount(Doc.ACCTTYPE_WriteOff, as)))
|
||||
{
|
||||
p_Error = "Cannot create Tax correction";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Realized Gain & Loss
|
||||
if (invoice != null
|
||||
&& (getC_Currency_ID() != as.getC_Currency_ID() // payment allocation in foreign currency
|
||||
|| getC_Currency_ID() != line.getInvoiceC_Currency_ID())) // allocation <> invoice currency
|
||||
{
|
||||
p_Error = createRealizedGainLoss (as, fact, bpAcct, invoice,
|
||||
allocationSource, allocationAccounted);
|
||||
if (p_Error != null)
|
||||
return null;
|
||||
}
|
||||
|
||||
} // for all lines
|
||||
|
||||
// reset line info
|
||||
setC_BPartner_ID(0);
|
||||
//
|
||||
m_facts.add(fact);
|
||||
return m_facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Create Cash Based Acct
|
||||
* @param as accounting schema
|
||||
* @param fact fact
|
||||
* @param invoice invoice
|
||||
* @param allocationSource allocation amount (incl discount, writeoff)
|
||||
* @return Accounted Amt
|
||||
*/
|
||||
private BigDecimal createCashBasedAcct (MAcctSchema as, Fact fact, MInvoice invoice,
|
||||
BigDecimal allocationSource)
|
||||
{
|
||||
BigDecimal allocationAccounted = Env.ZERO;
|
||||
// Multiplier
|
||||
double percent = invoice.getGrandTotal().doubleValue() / allocationSource.doubleValue();
|
||||
if (percent > 0.99 && percent < 1.01)
|
||||
percent = 1.0;
|
||||
log.config("Multiplier=" + percent + " - GrandTotal=" + invoice.getGrandTotal()
|
||||
+ " - Allocation Source=" + allocationSource);
|
||||
|
||||
// Get Invoice Postings
|
||||
Doc_Invoice docInvoice = (Doc_Invoice)Doc.get(new MAcctSchema[]{as},
|
||||
MInvoice.Table_ID, invoice.getC_Invoice_ID(), getTrxName());
|
||||
docInvoice.loadDocumentDetails();
|
||||
allocationAccounted = docInvoice.createFactCash(as, fact, new BigDecimal(percent));
|
||||
log.config("Allocation Accounted=" + allocationAccounted);
|
||||
|
||||
// Cash Based Commitment Release
|
||||
if (as.isCreateCommitment() && !invoice.isSOTrx())
|
||||
{
|
||||
MInvoiceLine[] lines = invoice.getLines();
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
Fact factC = Doc_Order.getCommitmentRelease(as, this,
|
||||
lines[i].getQtyInvoiced(), lines[i].getC_InvoiceLine_ID(), new BigDecimal(percent));
|
||||
if (factC == null)
|
||||
return null;
|
||||
m_facts.add(factC);
|
||||
}
|
||||
} // Commitment
|
||||
|
||||
return allocationAccounted;
|
||||
} // createCashBasedAcct
|
||||
|
||||
|
||||
/**
|
||||
* Get Payment (Unallocated Payment or Payment Selection) Acct of Bank Account
|
||||
* @param as accounting schema
|
||||
* @param C_Payment_ID payment
|
||||
* @return acct
|
||||
*/
|
||||
private MAccount getPaymentAcct (MAcctSchema as, int C_Payment_ID)
|
||||
{
|
||||
setC_BankAccount_ID(0);
|
||||
// Doc.ACCTTYPE_UnallocatedCash (AR) or C_Prepayment
|
||||
// or Doc.ACCTTYPE_PaymentSelect (AP) or V_Prepayment
|
||||
int accountType = Doc.ACCTTYPE_UnallocatedCash;
|
||||
//
|
||||
String sql = "SELECT p.C_BankAccount_ID, d.DocBaseType, p.IsReceipt, p.IsPrepayment "
|
||||
+ "FROM C_Payment p INNER JOIN C_DocType d ON (p.C_DocType_ID=d.C_DocType_ID) "
|
||||
+ "WHERE C_Payment_ID=?";
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, getTrxName());
|
||||
pstmt.setInt (1, C_Payment_ID);
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
if (rs.next ())
|
||||
{
|
||||
setC_BankAccount_ID(rs.getInt(1));
|
||||
if (DOCTYPE_APPayment.equals(rs.getString(2)))
|
||||
accountType = Doc.ACCTTYPE_PaymentSelect;
|
||||
// Prepayment
|
||||
if ("Y".equals(rs.getString(4))) // Prepayment
|
||||
{
|
||||
if ("Y".equals(rs.getString(3))) // Receipt
|
||||
accountType = Doc.ACCTTYPE_C_Prepayment;
|
||||
else
|
||||
accountType = Doc.ACCTTYPE_V_Prepayment;
|
||||
}
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
//
|
||||
if (getC_BankAccount_ID() <= 0)
|
||||
{
|
||||
log.log(Level.SEVERE, "NONE for C_Payment_ID=" + C_Payment_ID);
|
||||
return null;
|
||||
}
|
||||
return getAccount (accountType, as);
|
||||
} // getPaymentAcct
|
||||
|
||||
/**
|
||||
* Get Cash (Transfer) Acct of CashBook
|
||||
* @param as accounting schema
|
||||
* @param C_CashLine_ID
|
||||
* @return acct
|
||||
*/
|
||||
private MAccount getCashAcct (MAcctSchema as, int C_CashLine_ID)
|
||||
{
|
||||
String sql = "SELECT c.C_CashBook_ID "
|
||||
+ "FROM C_Cash c, C_CashLine cl "
|
||||
+ "WHERE c.C_Cash_ID=cl.C_Cash_ID AND cl.C_CashLine_ID=?";
|
||||
setC_CashBook_ID(DB.getSQLValue(null, sql, C_CashLine_ID));
|
||||
if (getC_CashBook_ID() <= 0)
|
||||
{
|
||||
log.log(Level.SEVERE, "NONE for C_CashLine_ID=" + C_CashLine_ID);
|
||||
return null;
|
||||
}
|
||||
return getAccount(Doc.ACCTTYPE_CashTransfer, as);
|
||||
} // getCashAcct
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Create Realized Gain & Loss.
|
||||
* Compares the Accounted Amount of the Invoice to the
|
||||
* Accounted Amount of the Allocation
|
||||
* @param as accounting schema
|
||||
* @param fact fact
|
||||
* @param acct account
|
||||
* @param invoice invoice
|
||||
* @param allocationSource source amt
|
||||
* @param allocationAccounted acct amt
|
||||
* @return Error Message or null if OK
|
||||
*/
|
||||
private String createRealizedGainLoss (MAcctSchema as, Fact fact, MAccount acct,
|
||||
MInvoice invoice, BigDecimal allocationSource, BigDecimal allocationAccounted)
|
||||
{
|
||||
BigDecimal invoiceSource = null;
|
||||
BigDecimal invoiceAccounted = null;
|
||||
//
|
||||
String sql = "SELECT "
|
||||
+ (invoice.isSOTrx()
|
||||
? "SUM(AmtSourceDr), SUM(AmtAcctDr)" // so
|
||||
: "SUM(AmtSourceCr), SUM(AmtAcctCr)") // po
|
||||
+ " FROM Fact_Acct "
|
||||
+ "WHERE AD_Table_ID=318 AND Record_ID=?" // Invoice
|
||||
+ " AND C_AcctSchema_ID=?"
|
||||
+ " AND PostingType='A'";
|
||||
//AND C_Currency_ID=102
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, getTrxName());
|
||||
pstmt.setInt(1, invoice.getC_Invoice_ID());
|
||||
pstmt.setInt(2, as.getC_AcctSchema_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
invoiceSource = rs.getBigDecimal(1);
|
||||
invoiceAccounted = rs.getBigDecimal(2);
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
// Requires that Invoice is Posted
|
||||
if (invoiceSource == null || invoiceAccounted == null)
|
||||
return "Gain/Loss - Invoice not posted yet";
|
||||
//
|
||||
String description = "Invoice=(" + invoice.getC_Currency_ID() + ")" + invoiceSource + "/" + invoiceAccounted
|
||||
+ " - Allocation=(" + getC_Currency_ID() + ")" + allocationSource + "/" + allocationAccounted;
|
||||
log.fine(description);
|
||||
// Allocation not Invoice Currency
|
||||
if (getC_Currency_ID() != invoice.getC_Currency_ID())
|
||||
{
|
||||
BigDecimal allocationSourceNew = MConversionRate.convert(getCtx(),
|
||||
allocationSource, getC_Currency_ID(),
|
||||
invoice.getC_Currency_ID(), getDateAcct(),
|
||||
invoice.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
|
||||
if (allocationSourceNew == null)
|
||||
return "Gain/Loss - No Conversion from Allocation->Invoice";
|
||||
String d2 = "Allocation=(" + getC_Currency_ID() + ")" + allocationSource
|
||||
+ "->(" + invoice.getC_Currency_ID() + ")" + allocationSourceNew;
|
||||
log.fine(d2);
|
||||
description += " - " + d2;
|
||||
allocationSource = allocationSourceNew;
|
||||
}
|
||||
|
||||
BigDecimal acctDifference = null; // gain is negative
|
||||
// Full Payment in currency
|
||||
if (allocationSource.compareTo(invoiceSource) == 0)
|
||||
{
|
||||
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
|
||||
String d2 = "(full) = " + acctDifference;
|
||||
log.fine(d2);
|
||||
description += " - " + d2;
|
||||
}
|
||||
else // partial or MC
|
||||
{
|
||||
// percent of total payment
|
||||
double multiplier = allocationSource.doubleValue() / invoiceSource.doubleValue();
|
||||
// Reduce Orig Invoice Accounted
|
||||
invoiceAccounted = invoiceAccounted.multiply(new BigDecimal(multiplier));
|
||||
// Difference based on percentage of Orig Invoice
|
||||
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
|
||||
// ignore Tolerance
|
||||
if (acctDifference.abs().compareTo(TOLERANCE) < 0)
|
||||
acctDifference = Env.ZERO;
|
||||
// Round
|
||||
int precision = as.getStdPrecision();
|
||||
if (acctDifference.scale() > precision)
|
||||
acctDifference = acctDifference.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||
String d2 = "(partial) = " + acctDifference + " - Multiplier=" + multiplier;
|
||||
log.fine(d2);
|
||||
description += " - " + d2;
|
||||
}
|
||||
|
||||
if (acctDifference.signum() == 0)
|
||||
{
|
||||
log.fine("No Difference");
|
||||
return null;
|
||||
}
|
||||
|
||||
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
|
||||
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
|
||||
//
|
||||
if (invoice.isSOTrx())
|
||||
{
|
||||
FactLine fl = fact.createLine (null, loss, gain,
|
||||
as.getC_Currency_ID(), acctDifference);
|
||||
fl.setDescription(description);
|
||||
fact.createLine (null, acct,
|
||||
as.getC_Currency_ID(), acctDifference.negate());
|
||||
fl.setDescription(description);
|
||||
}
|
||||
else
|
||||
{
|
||||
fact.createLine (null, acct,
|
||||
as.getC_Currency_ID(), acctDifference);
|
||||
FactLine fl = fact.createLine (null, loss, gain,
|
||||
as.getC_Currency_ID(), acctDifference.negate());
|
||||
}
|
||||
return null;
|
||||
} // createRealizedGainLoss
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Create Tax Correction.
|
||||
* Requirement: Adjust the tax amount, if you did not receive the full
|
||||
* amount of the invoice (payment discount, write-off).
|
||||
* Applies to many countries with VAT.
|
||||
* Example:
|
||||
* Invoice: Net $100 + Tax1 $15 + Tax2 $5 = Total $120
|
||||
* Payment: $115 (i.e. $5 underpayment)
|
||||
* Tax Adjustment = Tax1 = 0.63 (15/120*5) Tax2 = 0.21 (5/120/5)
|
||||
*
|
||||
* @param as accounting schema
|
||||
* @param fact fact
|
||||
* @param line Allocation line
|
||||
* @param DiscountAccount discount acct
|
||||
* @param WriteOffAccoint write off acct
|
||||
* @return true if created
|
||||
*/
|
||||
private boolean createTaxCorrection (MAcctSchema as, Fact fact,
|
||||
DocLine_Allocation line,
|
||||
MAccount DiscountAccount, MAccount WriteOffAccoint)
|
||||
{
|
||||
log.info (line.toString());
|
||||
BigDecimal discount = Env.ZERO;
|
||||
if (as.isTaxCorrectionDiscount())
|
||||
discount = line.getDiscountAmt();
|
||||
BigDecimal writeOff = Env.ZERO;
|
||||
if (as.isTaxCorrectionWriteOff())
|
||||
writeOff = line.getWriteOffAmt();
|
||||
|
||||
Doc_AllocationTax tax = new Doc_AllocationTax (
|
||||
DiscountAccount, discount, WriteOffAccoint, writeOff);
|
||||
|
||||
// Get Source Amounts with account
|
||||
String sql = "SELECT * "
|
||||
+ "FROM Fact_Acct "
|
||||
+ "WHERE AD_Table_ID=318 AND Record_ID=?" // Invoice
|
||||
+ " AND C_AcctSchema_ID=?"
|
||||
+ " AND Line_ID IS NULL"; // header lines like tax or total
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, getTrxName());
|
||||
pstmt.setInt(1, line.getC_Invoice_ID());
|
||||
pstmt.setInt(2, as.getC_AcctSchema_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
tax.addInvoiceFact (new MFactAcct(getCtx(), rs, fact.get_TrxName()));
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
// Invoice Not posted
|
||||
if (tax.getLineCount() == 0)
|
||||
{
|
||||
log.warning ("Invoice not posted yet - " + line);
|
||||
return false;
|
||||
}
|
||||
// size = 1 if no tax
|
||||
if (tax.getLineCount() < 2)
|
||||
return true;
|
||||
return tax.createEntries (as, fact, line);
|
||||
|
||||
} // createTaxCorrection
|
||||
|
||||
} // Doc_Allocation
|
||||
|
||||
/**
|
||||
* Allocation Document Tax Handing
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Allocation.java,v 1.6 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
class Doc_AllocationTax
|
||||
{
|
||||
/**
|
||||
* Allocation Tax Adjustment
|
||||
* @param DiscountAccount discount acct
|
||||
* @param DiscountAmt discount amt
|
||||
* @param WriteOffAccount write off acct
|
||||
* @param WriteOffAmt write off amt
|
||||
*/
|
||||
public Doc_AllocationTax (MAccount DiscountAccount, BigDecimal DiscountAmt,
|
||||
MAccount WriteOffAccount, BigDecimal WriteOffAmt)
|
||||
{
|
||||
m_DiscountAccount = DiscountAccount;
|
||||
m_DiscountAmt = DiscountAmt;
|
||||
m_WriteOffAccount = WriteOffAccount;
|
||||
m_WriteOffAmt = WriteOffAmt;
|
||||
} // Doc_AllocationTax
|
||||
|
||||
private CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
private MAccount m_DiscountAccount;
|
||||
private BigDecimal m_DiscountAmt;
|
||||
private MAccount m_WriteOffAccount;
|
||||
private BigDecimal m_WriteOffAmt;
|
||||
|
||||
private ArrayList<MFactAcct> m_facts = new ArrayList<MFactAcct>();
|
||||
private int m_totalIndex = 0;
|
||||
|
||||
/**
|
||||
* Add Invoice Fact Line
|
||||
* @param fact fact line
|
||||
*/
|
||||
public void addInvoiceFact (MFactAcct fact)
|
||||
{
|
||||
m_facts.add(fact);
|
||||
} // addInvoiceLine
|
||||
|
||||
/**
|
||||
* Get Line Count
|
||||
* @return number of lines
|
||||
*/
|
||||
public int getLineCount()
|
||||
{
|
||||
return m_facts.size();
|
||||
} // getLineCount
|
||||
|
||||
/**
|
||||
* Create Accounting Entries
|
||||
* @param as account schema
|
||||
* @param fact fact to add lines
|
||||
* @param line line
|
||||
* @return true if created
|
||||
*/
|
||||
public boolean createEntries (MAcctSchema as, Fact fact, DocLine line)
|
||||
{
|
||||
// get total index (the Receivables/Liabilities line)
|
||||
BigDecimal total = Env.ZERO;
|
||||
for (int i = 0; i < m_facts.size(); i++)
|
||||
{
|
||||
MFactAcct factAcct = (MFactAcct)m_facts.get(i);
|
||||
if (factAcct.getAmtSourceDr().compareTo(total) > 0)
|
||||
{
|
||||
total = factAcct.getAmtSourceDr();
|
||||
m_totalIndex = i;
|
||||
}
|
||||
if (factAcct.getAmtSourceCr().compareTo(total) > 0)
|
||||
{
|
||||
total = factAcct.getAmtSourceCr();
|
||||
m_totalIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
MFactAcct factAcct = (MFactAcct)m_facts.get(m_totalIndex);
|
||||
log.info ("Total Invoice = " + total + " - " + factAcct);
|
||||
int precision = as.getStdPrecision();
|
||||
for (int i = 0; i < m_facts.size(); i++)
|
||||
{
|
||||
// No Tax Line
|
||||
if (i == m_totalIndex)
|
||||
continue;
|
||||
|
||||
factAcct = (MFactAcct)m_facts.get(i);
|
||||
log.info (i + ": " + factAcct);
|
||||
|
||||
// Create Tax Account
|
||||
MAccount taxAcct = factAcct.getMAccount();
|
||||
if (taxAcct == null || taxAcct.get_ID() == 0)
|
||||
{
|
||||
log.severe ("Tax Account not found/created");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Discount Amount
|
||||
if (m_DiscountAmt.signum() != 0)
|
||||
{
|
||||
// Original Tax is DR - need to correct it CR
|
||||
if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
|
||||
{
|
||||
BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(),
|
||||
total, m_DiscountAmt, precision);
|
||||
if (amount.signum() != 0)
|
||||
{
|
||||
fact.createLine (line, m_DiscountAccount,
|
||||
as.getC_Currency_ID(), amount, null);
|
||||
fact.createLine (line, taxAcct,
|
||||
as.getC_Currency_ID(), null, amount);
|
||||
}
|
||||
}
|
||||
// Original Tax is CR - need to correct it DR
|
||||
else
|
||||
{
|
||||
BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(),
|
||||
total, m_DiscountAmt, precision);
|
||||
if (amount.signum() != 0)
|
||||
{
|
||||
fact.createLine (line, taxAcct,
|
||||
as.getC_Currency_ID(), amount, null);
|
||||
fact.createLine (line, m_DiscountAccount,
|
||||
as.getC_Currency_ID(), null, amount);
|
||||
}
|
||||
}
|
||||
} // Discount
|
||||
|
||||
// WriteOff Amount
|
||||
if (m_WriteOffAmt.signum() != 0)
|
||||
{
|
||||
// Original Tax is DR - need to correct it CR
|
||||
if (Env.ZERO.compareTo(factAcct.getAmtSourceDr()) != 0)
|
||||
{
|
||||
BigDecimal amount = calcAmount(factAcct.getAmtSourceDr(),
|
||||
total, m_WriteOffAmt, precision);
|
||||
if (amount.signum() != 0)
|
||||
{
|
||||
fact.createLine (line, m_WriteOffAccount,
|
||||
as.getC_Currency_ID(), amount, null);
|
||||
fact.createLine (line, taxAcct,
|
||||
as.getC_Currency_ID(), null, amount);
|
||||
}
|
||||
}
|
||||
// Original Tax is CR - need to correct it DR
|
||||
else
|
||||
{
|
||||
BigDecimal amount = calcAmount(factAcct.getAmtSourceCr(),
|
||||
total, m_WriteOffAmt, precision);
|
||||
if (amount.signum() != 0)
|
||||
{
|
||||
fact.createLine (line, taxAcct,
|
||||
as.getC_Currency_ID(), amount, null);
|
||||
fact.createLine (line, m_WriteOffAccount,
|
||||
as.getC_Currency_ID(), null, amount);
|
||||
}
|
||||
}
|
||||
} // WriteOff
|
||||
|
||||
} // for all lines
|
||||
return true;
|
||||
} // createEntries
|
||||
|
||||
/**
|
||||
* Calc Amount tax / (total-tax) * amt
|
||||
* @param tax tax
|
||||
* @param total total
|
||||
* @param amt reduction amt
|
||||
* @param precision precision
|
||||
* @return tax / total * amt
|
||||
*/
|
||||
private BigDecimal calcAmount (BigDecimal tax, BigDecimal total, BigDecimal amt, int precision)
|
||||
{
|
||||
log.fine("Amt=" + amt + " - Total=" + total + ", Tax=" + tax);
|
||||
if (tax.signum() == 0
|
||||
|| total.signum() == 0
|
||||
|| amt.signum() == 0)
|
||||
return Env.ZERO;
|
||||
//
|
||||
BigDecimal devisor = total.subtract(tax);
|
||||
BigDecimal multiplier = tax.divide(devisor, 10, BigDecimal.ROUND_HALF_UP);
|
||||
BigDecimal retValue = multiplier.multiply(amt);
|
||||
if (retValue.scale() > precision)
|
||||
retValue = retValue.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||
log.fine(retValue + " (Mult=" + multiplier + "(Prec=" + precision + ")");
|
||||
return retValue;
|
||||
} // calcAmount
|
||||
|
||||
} // Doc_AllocationTax
|
|
@ -0,0 +1,223 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: C_BankStatement (392)
|
||||
* Document Types: CMB
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Bank.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Bank extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Bank (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MBankStatement.class, rs, DOCTYPE_BankStatement, trxName);
|
||||
} // Doc_Bank
|
||||
|
||||
/** Bank Account */
|
||||
private int m_C_BankAccount_ID = 0;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MBankStatement bs = (MBankStatement)getPO();
|
||||
setDateDoc(bs.getStatementDate());
|
||||
setDateAcct(bs.getStatementDate()); // Overwritten on Line Level
|
||||
|
||||
m_C_BankAccount_ID = bs.getC_BankAccount_ID();
|
||||
// Amounts
|
||||
setAmount(AMTTYPE_Gross, bs.getStatementDifference());
|
||||
|
||||
// Set Bank Account Info (Currency)
|
||||
MBankAccount ba = MBankAccount.get (getCtx(), m_C_BankAccount_ID);
|
||||
setC_Currency_ID (ba.getC_Currency_ID());
|
||||
|
||||
// Contained Objects
|
||||
p_lines = loadLines(bs);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line.
|
||||
* @param bs bank statement
|
||||
* 4 amounts
|
||||
* AMTTYPE_Payment
|
||||
* AMTTYPE_Statement2
|
||||
* AMTTYPE_Charge
|
||||
* AMTTYPE_Interest
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MBankStatement bs)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MBankStatementLine[] lines = bs.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MBankStatementLine line = lines[i];
|
||||
DocLine_Bank docLine = new DocLine_Bank(line, this);
|
||||
// Set Date Acct
|
||||
if (i == 0)
|
||||
setDateAcct(line.getDateAcct());
|
||||
MPeriod period = MPeriod.get(getCtx(), line.getDateAcct());
|
||||
if (period != null && period.isOpen(DOCTYPE_BankStatement))
|
||||
docLine.setC_Period_ID(period.getC_Period_ID());
|
||||
//
|
||||
list.add(docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
StringBuffer sb = new StringBuffer (" [");
|
||||
// Total
|
||||
retValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));
|
||||
sb.append(getAmount(Doc.AMTTYPE_Gross));
|
||||
// - Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
BigDecimal lineBalance = ((DocLine_Bank)p_lines[i]).getStmtAmt();
|
||||
retValue = retValue.subtract(lineBalance);
|
||||
sb.append("-").append(lineBalance);
|
||||
}
|
||||
sb.append("]");
|
||||
//
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString());
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* CMB.
|
||||
* <pre>
|
||||
* BankAsset DR CR (Statement)
|
||||
* BankInTransit DR CR (Payment)
|
||||
* Charge DR (Charge)
|
||||
* Interest DR CR (Interest)
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
|
||||
// Header -- there may be different currency amounts
|
||||
|
||||
FactLine fl = null;
|
||||
int AD_Org_ID = getBank_Org_ID(); // Bank Account Org
|
||||
// Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine_Bank line = (DocLine_Bank)p_lines[i];
|
||||
int C_BPartner_ID = line.getC_BPartner_ID();
|
||||
|
||||
// BankAsset DR CR (Statement)
|
||||
fl = fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_BankAsset, as),
|
||||
line.getC_Currency_ID(), line.getStmtAmt());
|
||||
if (fl != null && AD_Org_ID != 0)
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
if (fl != null && C_BPartner_ID != 0)
|
||||
fl.setC_BPartner_ID(C_BPartner_ID);
|
||||
|
||||
// BankInTransit DR CR (Payment)
|
||||
fl = fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_BankInTransit, as),
|
||||
line.getC_Currency_ID(), line.getTrxAmt().negate());
|
||||
if (fl != null)
|
||||
{
|
||||
if (C_BPartner_ID != 0)
|
||||
fl.setC_BPartner_ID(C_BPartner_ID);
|
||||
if (AD_Org_ID != 0)
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
else
|
||||
fl.setAD_Org_ID(line.getAD_Org_ID(true)); // from payment
|
||||
}
|
||||
// Charge DR (Charge)
|
||||
fl = fact.createLine(line,
|
||||
line.getChargeAccount(as, line.getChargeAmt().negate()),
|
||||
line.getC_Currency_ID(), line.getChargeAmt().negate(), null);
|
||||
if (fl != null && C_BPartner_ID != 0)
|
||||
fl.setC_BPartner_ID(C_BPartner_ID);
|
||||
|
||||
// Interest DR CR (Interest)
|
||||
if (line.getInterestAmt().signum() < 0)
|
||||
fl = fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_InterestExp, as), getAccount(Doc.ACCTTYPE_InterestExp, as),
|
||||
line.getC_Currency_ID(), line.getInterestAmt().negate());
|
||||
else
|
||||
fl = fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_InterestRev, as), getAccount(Doc.ACCTTYPE_InterestRev, as),
|
||||
line.getC_Currency_ID(), line.getInterestAmt().negate());
|
||||
if (fl != null && C_BPartner_ID != 0)
|
||||
fl.setC_BPartner_ID(C_BPartner_ID);
|
||||
//
|
||||
// fact.createTaxCorrection();
|
||||
}
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Get AD_Org_ID from Bank Account
|
||||
* @return AD_Org_ID or 0
|
||||
*/
|
||||
private int getBank_Org_ID ()
|
||||
{
|
||||
if (m_C_BankAccount_ID == 0)
|
||||
return 0;
|
||||
//
|
||||
MBankAccount ba = MBankAccount.get(getCtx(), m_C_BankAccount_ID);
|
||||
return ba.getAD_Org_ID();
|
||||
} // getBank_Org_ID
|
||||
|
||||
} // Doc_Bank
|
|
@ -0,0 +1,254 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: C_Cash (407)
|
||||
* Document Types: CMC
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Cash.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Cash extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Cash (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super(ass, MCash.class, rs, DOCTYPE_CashJournal, trxName);
|
||||
} // Doc_Cash
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MCash cash = (MCash)getPO();
|
||||
setDateDoc(cash.getStatementDate());
|
||||
|
||||
// Amounts
|
||||
setAmount(Doc.AMTTYPE_Gross, cash.getStatementDifference());
|
||||
|
||||
// Set CashBook Org & Currency
|
||||
MCashBook cb = MCashBook.get(getCtx(), cash.getC_CashBook_ID());
|
||||
setC_CashBook_ID(cb.getC_CashBook_ID());
|
||||
setC_Currency_ID(cb.getC_Currency_ID());
|
||||
|
||||
// Contained Objects
|
||||
p_lines = loadLines(cash, cb);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**
|
||||
* Load Cash Line
|
||||
* @param cash journal
|
||||
* @param cb cash book
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MCash cash, MCashBook cb)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MCashLine[] lines = cash.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MCashLine line = lines[i];
|
||||
DocLine_Cash docLine = new DocLine_Cash (line, this);
|
||||
//
|
||||
list.add(docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
StringBuffer sb = new StringBuffer (" [");
|
||||
// Total
|
||||
retValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));
|
||||
sb.append(getAmount(Doc.AMTTYPE_Gross));
|
||||
// - Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
retValue = retValue.subtract(p_lines[i].getAmtSource());
|
||||
sb.append("-").append(p_lines[i].getAmtSource());
|
||||
}
|
||||
sb.append("]");
|
||||
//
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString());
|
||||
// return retValue;
|
||||
return Env.ZERO; // Lines are balanced
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* CMC.
|
||||
* <pre>
|
||||
* Expense
|
||||
* CashExpense DR
|
||||
* CashAsset CR
|
||||
* Receipt
|
||||
* CashAsset DR
|
||||
* CashReceipt CR
|
||||
* Charge
|
||||
* Charge DR
|
||||
* CashAsset CR
|
||||
* Difference
|
||||
* CashDifference DR
|
||||
* CashAsset CR
|
||||
* Invoice
|
||||
* CashAsset DR
|
||||
* CashTransfer CR
|
||||
* Transfer
|
||||
* BankInTransit DR
|
||||
* CashAsset CR
|
||||
* </pre>
|
||||
* @param as account schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// Need to have CashBook
|
||||
if (getC_CashBook_ID() == 0)
|
||||
{
|
||||
p_Error = "C_CashBook_ID not set";
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
|
||||
// Header posting amt as Invoices and Transfer could be differenet currency
|
||||
// CashAsset Total
|
||||
BigDecimal assetAmt = Env.ZERO;
|
||||
|
||||
// Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine_Cash line = (DocLine_Cash)p_lines[i];
|
||||
String CashType = line.getCashType();
|
||||
|
||||
if (CashType.equals(DocLine_Cash.CASHTYPE_EXPENSE))
|
||||
{ // amount is negative
|
||||
// CashExpense DR
|
||||
// CashAsset CR
|
||||
fact.createLine(line, getAccount(Doc.ACCTTYPE_CashExpense, as),
|
||||
getC_Currency_ID(), line.getAmount().negate(), null);
|
||||
// fact.createLine(line, getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
// p_vo.C_Currency_ID, null, line.getAmount().negate());
|
||||
assetAmt = assetAmt.subtract(line.getAmount().negate());
|
||||
}
|
||||
else if (CashType.equals(DocLine_Cash.CASHTYPE_RECEIPT))
|
||||
{ // amount is positive
|
||||
// CashAsset DR
|
||||
// CashReceipt CR
|
||||
// fact.createLine(line, getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
// p_vo.C_Currency_ID, line.getAmount(), null);
|
||||
assetAmt = assetAmt.add(line.getAmount());
|
||||
fact.createLine(line, getAccount(Doc.ACCTTYPE_CashReceipt, as),
|
||||
getC_Currency_ID(), null, line.getAmount());
|
||||
}
|
||||
else if (CashType.equals(DocLine_Cash.CASHTYPE_CHARGE))
|
||||
{ // amount is negative
|
||||
// Charge DR
|
||||
// CashAsset CR
|
||||
fact.createLine(line, line.getChargeAccount(as, getAmount()),
|
||||
getC_Currency_ID(), line.getAmount().negate(), null);
|
||||
// fact.createLine(line, getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
// p_vo.C_Currency_ID, null, line.getAmount().negate());
|
||||
assetAmt = assetAmt.subtract(line.getAmount().negate());
|
||||
}
|
||||
else if (CashType.equals(DocLine_Cash.CASHTYPE_DIFFERENCE))
|
||||
{ // amount is pos/neg
|
||||
// CashDifference DR
|
||||
// CashAsset CR
|
||||
fact.createLine(line, getAccount(Doc.ACCTTYPE_CashDifference, as),
|
||||
getC_Currency_ID(), line.getAmount().negate());
|
||||
// fact.createLine(line, getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
// p_vo.C_Currency_ID, line.getAmount());
|
||||
assetAmt = assetAmt.add(line.getAmount());
|
||||
}
|
||||
else if (CashType.equals(DocLine_Cash.CASHTYPE_INVOICE))
|
||||
{ // amount is pos/neg
|
||||
// CashAsset DR dr -- Invoice is in Invoice Currency !
|
||||
// CashTransfer cr CR
|
||||
if (line.getC_Currency_ID() == getC_Currency_ID())
|
||||
assetAmt = assetAmt.add (line.getAmount());
|
||||
else
|
||||
fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
line.getC_Currency_ID(), line.getAmount());
|
||||
fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_CashTransfer, as),
|
||||
line.getC_Currency_ID(), line.getAmount().negate());
|
||||
}
|
||||
else if (CashType.equals(DocLine_Cash.CASHTYPE_TRANSFER))
|
||||
{ // amount is pos/neg
|
||||
// BankInTransit DR dr -- Transfer is in Bank Account Currency
|
||||
// CashAsset dr CR
|
||||
int temp = getC_BankAccount_ID();
|
||||
setC_BankAccount_ID (line.getC_BankAccount_ID());
|
||||
fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_BankInTransit, as),
|
||||
line.getC_Currency_ID(), line.getAmount().negate());
|
||||
setC_BankAccount_ID(temp);
|
||||
if (line.getC_Currency_ID() == getC_Currency_ID())
|
||||
assetAmt = assetAmt.add (line.getAmount());
|
||||
else
|
||||
fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
line.getC_Currency_ID(), line.getAmount());
|
||||
}
|
||||
} // lines
|
||||
|
||||
// Cash Asset
|
||||
fact.createLine(null, getAccount(Doc.ACCTTYPE_CashAsset, as),
|
||||
getC_Currency_ID(), assetAmt);
|
||||
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
} // Doc_Cash
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: GL_Journal (224)
|
||||
* Document Types: GLJ
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_GLJournal.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_GLJournal extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_GLJournal (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super(ass, MJournal.class, rs, null, trxName);
|
||||
} // Foc_GL_Journal
|
||||
|
||||
/** Posting Type */
|
||||
private String m_PostingType = null;
|
||||
private int m_C_AcctSchema_ID = 0;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MJournal journal = (MJournal)getPO();
|
||||
m_PostingType = journal.getPostingType();
|
||||
m_C_AcctSchema_ID = journal.getC_AcctSchema_ID();
|
||||
|
||||
// Contained Objects
|
||||
p_lines = loadLines(journal);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param journal journal
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MJournal journal)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MJournalLine[] lines = journal.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MJournalLine line = lines[i];
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
// -- Source Amounts
|
||||
docLine.setAmount (line.getAmtSourceDr(), line.getAmtSourceCr());
|
||||
// -- Converted Amounts
|
||||
docLine.setConvertedAmt (m_C_AcctSchema_ID, line.getAmtAcctDr(), line.getAmtAcctCr());
|
||||
// -- Account
|
||||
MAccount account = line.getAccount();
|
||||
docLine.setAccount (account);
|
||||
// -- Organization of Line was set to Org of Account
|
||||
list.add(docLine);
|
||||
}
|
||||
// Return Array
|
||||
int size = list.size();
|
||||
DocLine[] dls = new DocLine[size];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
StringBuffer sb = new StringBuffer (" [");
|
||||
// Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
retValue = retValue.add(p_lines[i].getAmtSource());
|
||||
sb.append("+").append(p_lines[i].getAmtSource());
|
||||
}
|
||||
sb.append("]");
|
||||
//
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString());
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* GLJ.
|
||||
* (only for the accounting scheme, it was created)
|
||||
* <pre>
|
||||
* account DR CR
|
||||
* </pre>
|
||||
* @param as acct schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
// Other Acct Schema
|
||||
if (as.getC_AcctSchema_ID() != m_C_AcctSchema_ID)
|
||||
return facts;
|
||||
|
||||
// create Fact Header
|
||||
Fact fact = new Fact (this, as, m_PostingType);
|
||||
|
||||
// GLJ
|
||||
if (getDocumentType().equals(DOCTYPE_GLJournal))
|
||||
{
|
||||
// account DR CR
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
if (p_lines[i].getC_AcctSchema_ID () == as.getC_AcctSchema_ID ())
|
||||
{
|
||||
FactLine line = fact.createLine (p_lines[i],
|
||||
p_lines[i].getAccount (),
|
||||
getC_Currency_ID(),
|
||||
p_lines[i].getAmtSourceDr (),
|
||||
p_lines[i].getAmtSourceCr ());
|
||||
}
|
||||
} // for all lines
|
||||
}
|
||||
else
|
||||
{
|
||||
p_Error = "DocumentType unknown: " + getDocumentType();
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
fact = null;
|
||||
}
|
||||
//
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
} // Doc_GLJournal
|
|
@ -0,0 +1,283 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Shipment/Receipt Documents.
|
||||
* <pre>
|
||||
* Table: M_InOut (319)
|
||||
* Document Types: MMS, MMR
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_InOut.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_InOut extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
public Doc_InOut (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MInOut.class, rs, null, trxName);
|
||||
} // DocInOut
|
||||
|
||||
/**
|
||||
* Load Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID(NO_CURRENCY);
|
||||
MInOut inout = (MInOut)getPO();
|
||||
setDateDoc (inout.getMovementDate());
|
||||
// Contained Objects
|
||||
p_lines = loadLines(inout);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param inout shipment/receipt
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MInOut inout)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MInOutLine[] lines = inout.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MInOutLine line = lines[i];
|
||||
if (line.isDescription()
|
||||
|| line.getM_Product_ID() == 0
|
||||
|| line.getMovementQty().signum() == 0)
|
||||
{
|
||||
log.finer("Ignored: " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
BigDecimal Qty = line.getMovementQty();
|
||||
docLine.setQty (Qty, getDocumentType().equals(DOCTYPE_MatShipment)); // sets Trx and Storage Qty
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MMS, MMR.
|
||||
* <pre>
|
||||
* Shipment
|
||||
* CoGS (RevOrg) DR
|
||||
* Inventory CR
|
||||
* Shipment of Project Issue
|
||||
* CoGS DR
|
||||
* Project CR
|
||||
* Receipt
|
||||
* Inventory DR
|
||||
* NotInvoicedReceipt CR
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID (as.getC_Currency_ID());
|
||||
|
||||
// Line pointers
|
||||
FactLine dr = null;
|
||||
FactLine cr = null;
|
||||
|
||||
// *** Sales - Shipment
|
||||
if (getDocumentType().equals(DOCTYPE_MatShipment))
|
||||
{
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), true);
|
||||
if (costs == null || costs.signum() == 0) // zero costs OK
|
||||
{
|
||||
MProduct product = line.getProduct();
|
||||
if (product.isStocked())
|
||||
{
|
||||
p_Error = "No Costs for " + line.getProduct().getName();
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
else // ignore service
|
||||
continue;
|
||||
}
|
||||
// CoGS DR
|
||||
dr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Cogs, as),
|
||||
as.getC_Currency_ID(), costs, null);
|
||||
if (dr == null)
|
||||
{
|
||||
p_Error = "FactLine DR not created: " + line;
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
dr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||
dr.setAD_Org_ID(line.getOrder_Org_ID()); // Revenue X-Org
|
||||
dr.setQty(line.getQty().negate());
|
||||
|
||||
// Inventory CR
|
||||
cr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), null, costs);
|
||||
if (cr == null)
|
||||
{
|
||||
p_Error = "FactLine CR not created: " + line;
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
cr.setLocationFromLocator(line.getM_Locator_ID(), true); // from Loc
|
||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||
//
|
||||
if (line.getM_Product_ID() != 0)
|
||||
{
|
||||
MCostDetail.createShipment(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs, line.getQty(),
|
||||
line.getDescription(), true, getTrxName());
|
||||
}
|
||||
} // for all lines
|
||||
updateProductInfo(as.getC_AcctSchema_ID()); // only for SO!
|
||||
} // Shipment
|
||||
|
||||
// *** Purchasing - Receipt
|
||||
else if (getDocumentType().equals(DOCTYPE_MatReceipt))
|
||||
{
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // non-zero costs
|
||||
MProduct product = line.getProduct();
|
||||
if (costs == null || costs.signum() == 0)
|
||||
{
|
||||
p_Error = "Resubmit - No Costs for " + product.getName();
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
// Inventory/Asset DR
|
||||
MAccount assets = line.getAccount(ProductCost.ACCTTYPE_P_Asset, as);
|
||||
if (product.isService())
|
||||
assets = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
dr = fact.createLine(line, assets,
|
||||
as.getC_Currency_ID(), costs, null);
|
||||
if (dr == null)
|
||||
{
|
||||
p_Error = "DR not created: " + line;
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
dr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||
dr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||
// NotInvoicedReceipt CR
|
||||
cr = fact.createLine(line,
|
||||
getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as),
|
||||
as.getC_Currency_ID(), null, costs);
|
||||
if (cr == null)
|
||||
{
|
||||
p_Error = "CR not created: " + line;
|
||||
log.log(Level.WARNING, p_Error);
|
||||
return null;
|
||||
}
|
||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
cr.setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||
cr.setLocationFromLocator(line.getM_Locator_ID(), false); // to Loc
|
||||
cr.setQty(line.getQty().negate());
|
||||
}
|
||||
} // Receipt
|
||||
else
|
||||
{
|
||||
p_Error = "DocumentType unknown: " + getDocumentType();
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
|
||||
/**
|
||||
* Update Sales Order Costing Product Info (old).
|
||||
* Purchase side handeled in Invoice Matching.
|
||||
* <br>
|
||||
* decrease average cumulatives
|
||||
* @param C_AcctSchema_ID accounting schema
|
||||
* @deprecated old costing
|
||||
*/
|
||||
private void updateProductInfo (int C_AcctSchema_ID)
|
||||
{
|
||||
log.fine("M_InOut_ID=" + get_ID());
|
||||
// Old Model
|
||||
StringBuffer sql = new StringBuffer(
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET (CostAverageCumQty, CostAverageCumAmt)="
|
||||
+ "(SELECT CostAverageCumQty - SUM(il.MovementQty),"
|
||||
+ " CostAverageCumAmt - SUM(il.MovementQty*CurrentCostPrice) "
|
||||
+ "FROM M_InOutLine il "
|
||||
+ "WHERE pc.M_Product_ID=il.M_Product_ID"
|
||||
+ " AND il.M_InOut_ID=").append(get_ID()).append(") ")
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM M_InOutLine il "
|
||||
+ "WHERE pc.M_Product_ID=il.M_Product_ID"
|
||||
+ " AND il.M_InOut_ID=").append(get_ID()).append(")");
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - Updated=" + no);
|
||||
//
|
||||
} // updateProductInfo
|
||||
|
||||
} // Doc_InOut
|
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Inventory Documents.
|
||||
* <pre>
|
||||
* Table: M_Inventory (321)
|
||||
* Document Types: MMI
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Inventory.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Inventory extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
public Doc_Inventory (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MInventory.class, rs, DOCTYPE_MatInventory, trxName);
|
||||
} // Doc_Inventory
|
||||
|
||||
/**
|
||||
* Load Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID (NO_CURRENCY);
|
||||
MInventory inventory = (MInventory)getPO();
|
||||
setDateDoc (inventory.getMovementDate());
|
||||
setDateAcct(inventory.getMovementDate());
|
||||
// Contained Objects
|
||||
p_lines = loadLines(inventory);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param inventory inventory
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MInventory inventory)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MInventoryLine[] lines = inventory.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MInventoryLine line = lines[i];
|
||||
// nothing to post
|
||||
if (line.getQtyBook().compareTo(line.getQtyCount()) == 0
|
||||
&& line.getQtyInternalUse().signum() == 0)
|
||||
continue;
|
||||
//
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
BigDecimal Qty = line.getQtyInternalUse();
|
||||
if (Qty.signum() != 0)
|
||||
Qty = Qty.negate(); // Internal Use entered positive
|
||||
else
|
||||
{
|
||||
BigDecimal QtyBook = line.getQtyBook();
|
||||
BigDecimal QtyCount = line.getQtyCount();
|
||||
Qty = QtyCount.subtract(QtyBook);
|
||||
}
|
||||
docLine.setQty (Qty, false); // -5 => -5
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MMI.
|
||||
* <pre>
|
||||
* Inventory
|
||||
* Inventory DR CR
|
||||
* InventoryDiff DR CR (or Charge)
|
||||
* </pre>
|
||||
* @param as account schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID(as.getC_Currency_ID());
|
||||
|
||||
// Line pointers
|
||||
FactLine dr = null;
|
||||
FactLine cr = null;
|
||||
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
|
||||
if (costs == null || costs.signum() == 0)
|
||||
{
|
||||
p_Error = "No Costs for " + line.getProduct().getName();
|
||||
return null;
|
||||
}
|
||||
// Inventory DR CR
|
||||
dr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), costs);
|
||||
// may be zero difference - no line created.
|
||||
if (dr == null)
|
||||
continue;
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
|
||||
// InventoryDiff DR CR
|
||||
// or Charge
|
||||
MAccount invDiff = line.getChargeAccount(as, costs.negate());
|
||||
if (invDiff == null)
|
||||
invDiff = getAccount(Doc.ACCTTYPE_InvDifferences, as);
|
||||
cr = fact.createLine(line, invDiff,
|
||||
as.getC_Currency_ID(), costs.negate());
|
||||
if (cr == null)
|
||||
continue;
|
||||
cr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
cr.setQty(line.getQty().negate());
|
||||
if (line.getC_Charge_ID() != 0) // explicit overwrite for charge
|
||||
cr.setAD_Org_ID(line.getAD_Org_ID());
|
||||
|
||||
// Cost Detail
|
||||
MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs, line.getQty(),
|
||||
line.getDescription(), getTrxName());
|
||||
}
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
} // Doc_Inventory
|
|
@ -0,0 +1,953 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: C_Invoice (318)
|
||||
* Document Types: ARI, ARC, ARF, API, APC
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Invoice.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Invoice extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Invoice(MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MInvoice.class, rs, null, trxName);
|
||||
} // Doc_Invoice
|
||||
|
||||
/** Contained Optional Tax Lines */
|
||||
private DocTax[] m_taxes = null;
|
||||
/** Currency Precision */
|
||||
private int m_precision = -1;
|
||||
/** All lines are Service */
|
||||
private boolean m_allLinesService = true;
|
||||
/** All lines are product item */
|
||||
private boolean m_allLinesItem = true;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MInvoice invoice = (MInvoice)getPO();
|
||||
setDateDoc(invoice.getDateInvoiced());
|
||||
setIsTaxIncluded(invoice.isTaxIncluded());
|
||||
// Amounts
|
||||
setAmount(Doc.AMTTYPE_Gross, invoice.getGrandTotal());
|
||||
setAmount(Doc.AMTTYPE_Net, invoice.getTotalLines());
|
||||
setAmount(Doc.AMTTYPE_Charge, invoice.getChargeAmt());
|
||||
|
||||
// Contained Objects
|
||||
m_taxes = loadTaxes();
|
||||
p_lines = loadLines(invoice);
|
||||
log.fine("Lines=" + p_lines.length + ", Taxes=" + m_taxes.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Taxes
|
||||
* @return DocTax Array
|
||||
*/
|
||||
private DocTax[] loadTaxes()
|
||||
{
|
||||
ArrayList<DocTax> list = new ArrayList<DocTax>();
|
||||
String sql = "SELECT it.C_Tax_ID, t.Name, t.Rate, it.TaxBaseAmt, it.TaxAmt, t.IsSalesTax "
|
||||
+ "FROM C_Tax t, C_InvoiceTax it "
|
||||
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Invoice_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, getTrxName());
|
||||
pstmt.setInt(1, get_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
//
|
||||
while (rs.next())
|
||||
{
|
||||
int C_Tax_ID = rs.getInt(1);
|
||||
String name = rs.getString(2);
|
||||
BigDecimal rate = rs.getBigDecimal(3);
|
||||
BigDecimal taxBaseAmt = rs.getBigDecimal(4);
|
||||
BigDecimal amount = rs.getBigDecimal(5);
|
||||
boolean salesTax = "Y".equals(rs.getString(6));
|
||||
//
|
||||
DocTax taxLine = new DocTax(C_Tax_ID, name, rate,
|
||||
taxBaseAmt, amount, salesTax);
|
||||
log.fine(taxLine.toString());
|
||||
list.add(taxLine);
|
||||
}
|
||||
//
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocTax[] tl = new DocTax[list.size()];
|
||||
list.toArray(tl);
|
||||
return tl;
|
||||
} // loadTaxes
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param invoice invoice
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines (MInvoice invoice)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
//
|
||||
MInvoiceLine[] lines = invoice.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MInvoiceLine line = lines[i];
|
||||
if (line.isDescription())
|
||||
continue;
|
||||
DocLine docLine = new DocLine(line, this);
|
||||
// Qty
|
||||
BigDecimal Qty = line.getQtyInvoiced();
|
||||
boolean cm = getDocumentType().equals(DOCTYPE_ARCredit)
|
||||
|| getDocumentType().equals(DOCTYPE_APCredit);
|
||||
docLine.setQty(cm ? Qty.negate() : Qty, invoice.isSOTrx());
|
||||
//
|
||||
BigDecimal LineNetAmt = line.getLineNetAmt();
|
||||
BigDecimal PriceList = line.getPriceList();
|
||||
int C_Tax_ID = docLine.getC_Tax_ID();
|
||||
// Correct included Tax
|
||||
if (isTaxIncluded() && C_Tax_ID != 0)
|
||||
{
|
||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||
if (!tax.isZeroTax())
|
||||
{
|
||||
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, getStdPercision());
|
||||
log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
|
||||
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
||||
for (int t = 0; t < m_taxes.length; t++)
|
||||
{
|
||||
if (m_taxes[t].getC_Tax_ID() == C_Tax_ID)
|
||||
{
|
||||
m_taxes[t].addIncludedTax(LineNetAmtTax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, getStdPercision());
|
||||
PriceList = PriceList.subtract(PriceListTax);
|
||||
}
|
||||
} // correct included Tax
|
||||
|
||||
docLine.setAmount (LineNetAmt, PriceList, Qty); // qty for discount calc
|
||||
if (docLine.isItem())
|
||||
m_allLinesService = false;
|
||||
else
|
||||
m_allLinesItem = false;
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add(docLine);
|
||||
}
|
||||
|
||||
// Convert to Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
|
||||
// Included Tax - make sure that no difference
|
||||
if (isTaxIncluded())
|
||||
{
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
if (m_taxes[i].isIncludedTaxDifference())
|
||||
{
|
||||
BigDecimal diff = m_taxes[i].getIncludedTaxDifference();
|
||||
for (int j = 0; j < dls.length; j++)
|
||||
{
|
||||
if (dls[j].getC_Tax_ID() == m_taxes[i].getC_Tax_ID())
|
||||
{
|
||||
dls[j].setLineNetAmtDifference(diff);
|
||||
break;
|
||||
}
|
||||
} // for all lines
|
||||
} // tax difference
|
||||
} // for all taxes
|
||||
} // Included Tax difference
|
||||
|
||||
// Return Array
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
/**
|
||||
* Get Currency Percision
|
||||
* @return precision
|
||||
*/
|
||||
private int getStdPercision()
|
||||
{
|
||||
if (m_precision == -1)
|
||||
m_precision = MCurrency.getStdPrecision(getCtx(), getC_Currency_ID());
|
||||
return m_precision;
|
||||
} // getPrecision
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
StringBuffer sb = new StringBuffer (" [");
|
||||
// Total
|
||||
retValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));
|
||||
sb.append(getAmount(Doc.AMTTYPE_Gross));
|
||||
// - Header Charge
|
||||
retValue = retValue.subtract(getAmount(Doc.AMTTYPE_Charge));
|
||||
sb.append("-").append(getAmount(Doc.AMTTYPE_Charge));
|
||||
// - Tax
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
retValue = retValue.subtract(m_taxes[i].getAmount());
|
||||
sb.append("-").append(m_taxes[i].getAmount());
|
||||
}
|
||||
// - Lines
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
retValue = retValue.subtract(p_lines[i].getAmtSource());
|
||||
sb.append("-").append(p_lines[i].getAmtSource());
|
||||
}
|
||||
sb.append("]");
|
||||
//
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString());
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* ARI, ARC, ARF, API, APC.
|
||||
* <pre>
|
||||
* ARI, ARF
|
||||
* Receivables DR
|
||||
* Charge CR
|
||||
* TaxDue CR
|
||||
* Revenue CR
|
||||
*
|
||||
* ARC
|
||||
* Receivables CR
|
||||
* Charge DR
|
||||
* TaxDue DR
|
||||
* Revenue RR
|
||||
*
|
||||
* API
|
||||
* Payables CR
|
||||
* Charge DR
|
||||
* TaxCredit DR
|
||||
* Expense DR
|
||||
*
|
||||
* APC
|
||||
* Payables DR
|
||||
* Charge CR
|
||||
* TaxCredit CR
|
||||
* Expense CR
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
|
||||
// Cash based accounting
|
||||
if (!as.isAccrual())
|
||||
return facts;
|
||||
|
||||
// ** ARI, ARF
|
||||
if (getDocumentType().equals(DOCTYPE_ARInvoice)
|
||||
|| getDocumentType().equals(DOCTYPE_ARProForma))
|
||||
{
|
||||
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
BigDecimal serviceAmt = Env.ZERO;
|
||||
|
||||
// Header Charge CR
|
||||
BigDecimal amt = getAmount(Doc.AMTTYPE_Charge);
|
||||
if (amt != null && amt.signum() != 0)
|
||||
fact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),
|
||||
getC_Currency_ID(), null, amt);
|
||||
// TaxDue CR
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
amt = m_taxes[i].getAmount();
|
||||
if (amt != null && amt.signum() != 0)
|
||||
{
|
||||
FactLine tl = fact.createLine(null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),
|
||||
getC_Currency_ID(), null, amt);
|
||||
if (tl != null)
|
||||
tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
|
||||
}
|
||||
}
|
||||
// Revenue CR
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
amt = p_lines[i].getAmtSource();
|
||||
BigDecimal dAmt = null;
|
||||
if (as.isTradeDiscountPosted())
|
||||
{
|
||||
BigDecimal discount = p_lines[i].getDiscount();
|
||||
if (discount != null && discount.signum() != 0)
|
||||
{
|
||||
amt = amt.add(discount);
|
||||
dAmt = discount;
|
||||
}
|
||||
}
|
||||
fact.createLine (p_lines[i],
|
||||
p_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as),
|
||||
getC_Currency_ID(), dAmt, amt);
|
||||
if (!p_lines[i].isItem())
|
||||
{
|
||||
grossAmt = grossAmt.subtract(amt);
|
||||
serviceAmt = serviceAmt.add(amt);
|
||||
}
|
||||
}
|
||||
// Set Locations
|
||||
FactLine[] fLines = fact.getLines();
|
||||
for (int i = 0; i < fLines.length; i++)
|
||||
{
|
||||
if (fLines[i] != null)
|
||||
{
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||
}
|
||||
}
|
||||
|
||||
// Receivables DR
|
||||
int receivables_ID = getValidCombination_ID(Doc.ACCTTYPE_C_Receivable, as);
|
||||
int receivablesServices_ID = getValidCombination_ID (Doc.ACCTTYPE_C_Receivable_Services, as);
|
||||
if (m_allLinesItem || !as.isPostServices()
|
||||
|| receivables_ID == receivablesServices_ID)
|
||||
{
|
||||
grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
serviceAmt = Env.ZERO;
|
||||
}
|
||||
else if (m_allLinesService)
|
||||
{
|
||||
serviceAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
grossAmt = Env.ZERO;
|
||||
}
|
||||
if (grossAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), receivables_ID),
|
||||
getC_Currency_ID(), grossAmt, null);
|
||||
if (serviceAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), receivablesServices_ID),
|
||||
getC_Currency_ID(), serviceAmt, null);
|
||||
}
|
||||
// ARC
|
||||
else if (getDocumentType().equals(DOCTYPE_ARCredit))
|
||||
{
|
||||
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
BigDecimal serviceAmt = Env.ZERO;
|
||||
|
||||
// Header Charge DR
|
||||
BigDecimal amt = getAmount(Doc.AMTTYPE_Charge);
|
||||
if (amt != null && amt.signum() != 0)
|
||||
fact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),
|
||||
getC_Currency_ID(), amt, null);
|
||||
// TaxDue DR
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
amt = m_taxes[i].getAmount();
|
||||
if (amt != null && amt.signum() != 0)
|
||||
{
|
||||
FactLine tl = fact.createLine(null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),
|
||||
getC_Currency_ID(), amt, null);
|
||||
if (tl != null)
|
||||
tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
|
||||
}
|
||||
}
|
||||
// Revenue CR
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
amt = p_lines[i].getAmtSource();
|
||||
BigDecimal dAmt = null;
|
||||
if (as.isTradeDiscountPosted())
|
||||
{
|
||||
BigDecimal discount = p_lines[i].getDiscount();
|
||||
if (discount != null && discount.signum() != 0)
|
||||
{
|
||||
amt = amt.add(discount);
|
||||
dAmt = discount;
|
||||
}
|
||||
}
|
||||
fact.createLine (p_lines[i],
|
||||
p_lines[i].getAccount (ProductCost.ACCTTYPE_P_Revenue, as),
|
||||
getC_Currency_ID(), amt, dAmt);
|
||||
if (!p_lines[i].isItem())
|
||||
{
|
||||
grossAmt = grossAmt.subtract(amt);
|
||||
serviceAmt = serviceAmt.add(amt);
|
||||
}
|
||||
}
|
||||
// Set Locations
|
||||
FactLine[] fLines = fact.getLines();
|
||||
for (int i = 0; i < fLines.length; i++)
|
||||
{
|
||||
if (fLines[i] != null)
|
||||
{
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||
}
|
||||
}
|
||||
// Receivables CR
|
||||
int receivables_ID = getValidCombination_ID (Doc.ACCTTYPE_C_Receivable, as);
|
||||
int receivablesServices_ID = getValidCombination_ID (Doc.ACCTTYPE_C_Receivable_Services, as);
|
||||
if (m_allLinesItem || !as.isPostServices()
|
||||
|| receivables_ID == receivablesServices_ID)
|
||||
{
|
||||
grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
serviceAmt = Env.ZERO;
|
||||
}
|
||||
else if (m_allLinesService)
|
||||
{
|
||||
serviceAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
grossAmt = Env.ZERO;
|
||||
}
|
||||
if (grossAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), receivables_ID),
|
||||
getC_Currency_ID(), null, grossAmt);
|
||||
if (serviceAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), receivablesServices_ID),
|
||||
getC_Currency_ID(), null, serviceAmt);
|
||||
}
|
||||
|
||||
// ** API
|
||||
else if (getDocumentType().equals(DOCTYPE_APInvoice))
|
||||
{
|
||||
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
BigDecimal serviceAmt = Env.ZERO;
|
||||
|
||||
// Charge DR
|
||||
fact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),
|
||||
getC_Currency_ID(), getAmount(Doc.AMTTYPE_Charge), null);
|
||||
// TaxCredit DR
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
FactLine tl = fact.createLine(null, m_taxes[i].getAccount(m_taxes[i].getAPTaxType(), as),
|
||||
getC_Currency_ID(), m_taxes[i].getAmount(), null);
|
||||
if (tl != null)
|
||||
tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
|
||||
}
|
||||
// Expense DR
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
boolean landedCost = landedCost(as, fact, line, true);
|
||||
if (landedCost && as.isExplicitCostAdjustment())
|
||||
{
|
||||
fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
//
|
||||
FactLine fl = fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), null, line.getAmtSource());
|
||||
String desc = line.getDescription();
|
||||
if (desc == null)
|
||||
desc = "100%";
|
||||
else
|
||||
desc += " 100%";
|
||||
fl.setDescription(desc);
|
||||
}
|
||||
if (!landedCost)
|
||||
{
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
if (line.isItem())
|
||||
expense = line.getAccount (ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
BigDecimal amt = line.getAmtSource();
|
||||
BigDecimal dAmt = null;
|
||||
if (as.isTradeDiscountPosted() && !line.isItem())
|
||||
{
|
||||
BigDecimal discount = line.getDiscount();
|
||||
if (discount != null && discount.signum() != 0)
|
||||
{
|
||||
amt = amt.add(discount);
|
||||
dAmt = discount;
|
||||
}
|
||||
}
|
||||
fact.createLine (line, expense,
|
||||
getC_Currency_ID(), amt, dAmt);
|
||||
if (!line.isItem())
|
||||
{
|
||||
grossAmt = grossAmt.subtract(amt);
|
||||
serviceAmt = serviceAmt.add(amt);
|
||||
}
|
||||
//
|
||||
if (line.getM_Product_ID() != 0
|
||||
&& line.getProduct().isService()) // otherwise Inv Matching
|
||||
MCostDetail.createInvoice(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0, // No Cost Element
|
||||
line.getAmtSource(), line.getQty(),
|
||||
line.getDescription(), getTrxName());
|
||||
}
|
||||
}
|
||||
// Set Locations
|
||||
FactLine[] fLines = fact.getLines();
|
||||
for (int i = 0; i < fLines.length; i++)
|
||||
{
|
||||
if (fLines[i] != null)
|
||||
{
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), false); // to Loc
|
||||
}
|
||||
}
|
||||
|
||||
// Liability CR
|
||||
int payables_ID = getValidCombination_ID (Doc.ACCTTYPE_V_Liability, as);
|
||||
int payablesServices_ID = getValidCombination_ID (Doc.ACCTTYPE_V_Liability_Services, as);
|
||||
if (m_allLinesItem || !as.isPostServices()
|
||||
|| payables_ID == payablesServices_ID)
|
||||
{
|
||||
grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
serviceAmt = Env.ZERO;
|
||||
}
|
||||
else if (m_allLinesService)
|
||||
{
|
||||
serviceAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
grossAmt = Env.ZERO;
|
||||
}
|
||||
if (grossAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), payables_ID),
|
||||
getC_Currency_ID(), null, grossAmt);
|
||||
if (serviceAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), payablesServices_ID),
|
||||
getC_Currency_ID(), null, serviceAmt);
|
||||
//
|
||||
updateProductPO(as); // Only API
|
||||
updateProductInfo (as.getC_AcctSchema_ID()); // only API
|
||||
}
|
||||
// APC
|
||||
else if (getDocumentType().equals(DOCTYPE_APCredit))
|
||||
{
|
||||
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
BigDecimal serviceAmt = Env.ZERO;
|
||||
// Charge CR
|
||||
fact.createLine (null, getAccount(Doc.ACCTTYPE_Charge, as),
|
||||
getC_Currency_ID(), null, getAmount(Doc.AMTTYPE_Charge));
|
||||
// TaxCredit CR
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
FactLine tl = fact.createLine (null, m_taxes[i].getAccount(m_taxes[i].getAPTaxType(), as),
|
||||
getC_Currency_ID(), null, m_taxes[i].getAmount());
|
||||
if (tl != null)
|
||||
tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
|
||||
}
|
||||
// Expense CR
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
boolean landedCost = landedCost(as, fact, line, false);
|
||||
if (landedCost && as.isExplicitCostAdjustment())
|
||||
{
|
||||
fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), null, line.getAmtSource());
|
||||
//
|
||||
FactLine fl = fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
String desc = line.getDescription();
|
||||
if (desc == null)
|
||||
desc = "100%";
|
||||
else
|
||||
desc += " 100%";
|
||||
fl.setDescription(desc);
|
||||
}
|
||||
if (!landedCost)
|
||||
{
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
if (line.isItem())
|
||||
expense = line.getAccount (ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
BigDecimal amt = line.getAmtSource();
|
||||
BigDecimal dAmt = null;
|
||||
if (as.isTradeDiscountPosted() && !line.isItem())
|
||||
{
|
||||
BigDecimal discount = line.getDiscount();
|
||||
if (discount != null && discount.signum() != 0)
|
||||
{
|
||||
amt = amt.add(discount);
|
||||
dAmt = discount;
|
||||
}
|
||||
}
|
||||
fact.createLine (line, expense,
|
||||
getC_Currency_ID(), dAmt, amt);
|
||||
if (!line.isItem())
|
||||
{
|
||||
grossAmt = grossAmt.subtract(amt);
|
||||
serviceAmt = serviceAmt.add(amt);
|
||||
}
|
||||
//
|
||||
if (line.getM_Product_ID() != 0
|
||||
&& line.getProduct().isService()) // otherwise Inv Matching
|
||||
MCostDetail.createInvoice(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0, // No Cost Element
|
||||
line.getAmtSource().negate(), line.getQty(),
|
||||
line.getDescription(), getTrxName());
|
||||
}
|
||||
}
|
||||
// Set Locations
|
||||
FactLine[] fLines = fact.getLines();
|
||||
for (int i = 0; i < fLines.length; i++)
|
||||
{
|
||||
if (fLines[i] != null)
|
||||
{
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), false); // to Loc
|
||||
}
|
||||
}
|
||||
// Liability DR
|
||||
int payables_ID = getValidCombination_ID (Doc.ACCTTYPE_V_Liability, as);
|
||||
int payablesServices_ID = getValidCombination_ID (Doc.ACCTTYPE_V_Liability_Services, as);
|
||||
if (m_allLinesItem || !as.isPostServices()
|
||||
|| payables_ID == payablesServices_ID)
|
||||
{
|
||||
grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
serviceAmt = Env.ZERO;
|
||||
}
|
||||
else if (m_allLinesService)
|
||||
{
|
||||
serviceAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
grossAmt = Env.ZERO;
|
||||
}
|
||||
if (grossAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), payables_ID),
|
||||
getC_Currency_ID(), grossAmt, null);
|
||||
if (serviceAmt.signum() != 0)
|
||||
fact.createLine(null, MAccount.get(getCtx(), payablesServices_ID),
|
||||
getC_Currency_ID(), serviceAmt, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_Error = "DocumentType unknown: " + getDocumentType();
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
fact = null;
|
||||
}
|
||||
//
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Create Fact Cash Based (i.e. only revenue/expense)
|
||||
* @param as accounting schema
|
||||
* @param fact fact to add lines to
|
||||
* @param multiplier source amount multiplier
|
||||
* @return accounted amount
|
||||
*/
|
||||
public BigDecimal createFactCash (MAcctSchema as, Fact fact, BigDecimal multiplier)
|
||||
{
|
||||
boolean creditMemo = getDocumentType().equals(DOCTYPE_ARCredit)
|
||||
|| getDocumentType().equals(DOCTYPE_APCredit);
|
||||
boolean payables = getDocumentType().equals(DOCTYPE_APInvoice)
|
||||
|| getDocumentType().equals(DOCTYPE_APCredit);
|
||||
BigDecimal acctAmt = Env.ZERO;
|
||||
FactLine fl = null;
|
||||
// Revenue/Cost
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
boolean landedCost = false;
|
||||
if (payables)
|
||||
landedCost = landedCost(as, fact, line, false);
|
||||
if (landedCost && as.isExplicitCostAdjustment())
|
||||
{
|
||||
fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), null, line.getAmtSource());
|
||||
//
|
||||
fl = fact.createLine (line, line.getAccount(ProductCost.ACCTTYPE_P_Expense, as),
|
||||
getC_Currency_ID(), line.getAmtSource(), null);
|
||||
String desc = line.getDescription();
|
||||
if (desc == null)
|
||||
desc = "100%";
|
||||
else
|
||||
desc += " 100%";
|
||||
fl.setDescription(desc);
|
||||
}
|
||||
if (!landedCost)
|
||||
{
|
||||
MAccount acct = line.getAccount(
|
||||
payables ? ProductCost.ACCTTYPE_P_Expense : ProductCost.ACCTTYPE_P_Revenue, as);
|
||||
if (payables)
|
||||
{
|
||||
// if Fixed Asset
|
||||
if (line.isItem())
|
||||
acct = line.getAccount (ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
}
|
||||
BigDecimal amt = line.getAmtSource().multiply(multiplier);
|
||||
BigDecimal amt2 = null;
|
||||
if (creditMemo)
|
||||
{
|
||||
amt2 = amt;
|
||||
amt = null;
|
||||
}
|
||||
if (payables) // Vendor = DR
|
||||
fl = fact.createLine (line, acct,
|
||||
getC_Currency_ID(), amt, amt2);
|
||||
else // Customer = CR
|
||||
fl = fact.createLine (line, acct,
|
||||
getC_Currency_ID(), amt2, amt);
|
||||
if (fl != null)
|
||||
acctAmt = acctAmt.add(fl.getAcctBalance());
|
||||
}
|
||||
}
|
||||
// Tax
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
BigDecimal amt = m_taxes[i].getAmount();
|
||||
BigDecimal amt2 = null;
|
||||
if (creditMemo)
|
||||
{
|
||||
amt2 = amt;
|
||||
amt = null;
|
||||
}
|
||||
FactLine tl = null;
|
||||
if (payables)
|
||||
tl = fact.createLine (null, m_taxes[i].getAccount(m_taxes[i].getAPTaxType(), as),
|
||||
getC_Currency_ID(), amt, amt2);
|
||||
else
|
||||
tl = fact.createLine (null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),
|
||||
getC_Currency_ID(), amt2, amt);
|
||||
if (tl != null)
|
||||
tl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());
|
||||
}
|
||||
// Set Locations
|
||||
FactLine[] fLines = fact.getLines();
|
||||
for (int i = 0; i < fLines.length; i++)
|
||||
{
|
||||
if (fLines[i] != null)
|
||||
{
|
||||
if (payables)
|
||||
{
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), false); // to Loc
|
||||
}
|
||||
else
|
||||
{
|
||||
fLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true); // from Loc
|
||||
fLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false); // to Loc
|
||||
}
|
||||
}
|
||||
}
|
||||
return acctAmt;
|
||||
} // createFactCash
|
||||
|
||||
|
||||
/**
|
||||
* Create Landed Cost accounting & Cost lines
|
||||
* @param as accounting schema
|
||||
* @param fact fact
|
||||
* @param line document line
|
||||
* @param dr DR entry (normal api)
|
||||
* @return true if landed costs were created
|
||||
*/
|
||||
private boolean landedCost (MAcctSchema as, Fact fact, DocLine line, boolean dr)
|
||||
{
|
||||
int C_InvoiceLine_ID = line.get_ID();
|
||||
MLandedCostAllocation[] lcas = MLandedCostAllocation.getOfInvoiceLine(
|
||||
getCtx(), C_InvoiceLine_ID, getTrxName());
|
||||
if (lcas.length == 0)
|
||||
return false;
|
||||
|
||||
// Delete Old
|
||||
String sql = "DELETE M_CostDetail WHERE C_InvoiceLine_ID=" + C_InvoiceLine_ID;
|
||||
int no = DB.executeUpdate(sql, getTrxName());
|
||||
if (no != 0)
|
||||
log.config("CostDetail Deleted #" + no);
|
||||
|
||||
// Calculate Total Base
|
||||
double totalBase = 0;
|
||||
for (int i = 0; i < lcas.length; i++)
|
||||
totalBase += lcas[i].getBase().doubleValue();
|
||||
|
||||
// Create New
|
||||
MInvoiceLine il = new MInvoiceLine (getCtx(), C_InvoiceLine_ID, getTrxName());
|
||||
for (int i = 0; i < lcas.length; i++)
|
||||
{
|
||||
MLandedCostAllocation lca = lcas[i];
|
||||
if (lca.getBase().signum() == 0)
|
||||
continue;
|
||||
double percent = totalBase / lca.getBase().doubleValue();
|
||||
String desc = il.getDescription();
|
||||
if (desc == null)
|
||||
desc = percent + "%";
|
||||
else
|
||||
desc += " - " + percent + "%";
|
||||
if (line.getDescription() != null)
|
||||
desc += " - " + line.getDescription();
|
||||
|
||||
// Accounting
|
||||
ProductCost pc = new ProductCost (Env.getCtx(),
|
||||
lca.getM_Product_ID(), lca.getM_AttributeSetInstance_ID(), getTrxName());
|
||||
BigDecimal drAmt = null;
|
||||
BigDecimal crAmt = null;
|
||||
if (dr)
|
||||
drAmt = lca.getAmt();
|
||||
else
|
||||
crAmt = lca.getAmt();
|
||||
FactLine fl = fact.createLine (line, pc.getAccount(ProductCost.ACCTTYPE_P_CostAdjustment, as),
|
||||
getC_Currency_ID(), drAmt, crAmt);
|
||||
fl.setDescription(desc);
|
||||
|
||||
// Cost Detail - Convert to AcctCurrency
|
||||
BigDecimal allocationAmt = lca.getAmt();
|
||||
if (getC_Currency_ID() != as.getC_Currency_ID())
|
||||
allocationAmt = MConversionRate.convert(getCtx(), allocationAmt,
|
||||
getC_Currency_ID(), as.getC_Currency_ID(),
|
||||
getDateAcct(), getC_ConversionType_ID(),
|
||||
getAD_Client_ID(), getAD_Org_ID());
|
||||
if (allocationAmt.scale() > as.getCostingPrecision())
|
||||
allocationAmt = allocationAmt.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
||||
if (!dr)
|
||||
allocationAmt = allocationAmt.negate();
|
||||
MCostDetail cd = new MCostDetail (as, lca.getAD_Org_ID(),
|
||||
lca.getM_Product_ID(), lca.getM_AttributeSetInstance_ID(),
|
||||
lca.getM_CostElement_ID(),
|
||||
allocationAmt, Env.ZERO, // Qty
|
||||
desc, getTrxName());
|
||||
cd.setC_InvoiceLine_ID(C_InvoiceLine_ID);
|
||||
boolean ok = cd.save();
|
||||
if (ok && !cd.isProcessed())
|
||||
{
|
||||
MClient client = MClient.get(as.getCtx(), as.getAD_Client_ID());
|
||||
if (client.isCostImmediate())
|
||||
cd.process();
|
||||
}
|
||||
}
|
||||
|
||||
log.config("Created #" + lcas.length);
|
||||
return true;
|
||||
} // landedCosts
|
||||
|
||||
/**
|
||||
* Update ProductPO PriceLastInv
|
||||
* @param as accounting schema
|
||||
*/
|
||||
private void updateProductPO (MAcctSchema as)
|
||||
{
|
||||
MClientInfo ci = MClientInfo.get(getCtx(), as.getAD_Client_ID());
|
||||
if (ci.getC_AcctSchema1_ID() != as.getC_AcctSchema_ID())
|
||||
return;
|
||||
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_PO po "
|
||||
+ "SET PriceLastInv = "
|
||||
// select
|
||||
+ "(SELECT currencyConvert(il.PriceActual,i.C_Currency_ID,po.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID) "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND po.M_Product_ID=il.M_Product_ID AND po.C_BPartner_ID=i.C_BPartner_ID"
|
||||
+ " AND ROWNUM=1 AND i.C_Invoice_ID=").append(get_ID()).append(") ")
|
||||
// update
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND po.M_Product_ID=il.M_Product_ID AND po.C_BPartner_ID=i.C_BPartner_ID"
|
||||
+ " AND i.C_Invoice_ID=").append(get_ID()).append(")");
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("Updated=" + no);
|
||||
} // updateProductPO
|
||||
|
||||
/**
|
||||
* Update Product Info (old).
|
||||
* - Costing (PriceLastInv)
|
||||
* - PO (PriceLastInv)
|
||||
* @param C_AcctSchema_ID accounting schema
|
||||
* @deprecated old costing
|
||||
*/
|
||||
private void updateProductInfo (int C_AcctSchema_ID)
|
||||
{
|
||||
log.fine("C_Invoice_ID=" + get_ID());
|
||||
|
||||
/** @todo Last.. would need to compare document/last updated date
|
||||
* would need to maintain LastPriceUpdateDate on _PO and _Costing */
|
||||
|
||||
// update Product Costing
|
||||
// requires existence of currency conversion !!
|
||||
// if there are multiple lines of the same product last price uses first
|
||||
// -> TotalInvAmt is sometimes NULL !! -> error
|
||||
// begin globalqss 2005-10-19
|
||||
// postgresql doesn't support LIMIT on UPDATE or DELETE statements
|
||||
/*
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET (PriceLastInv, TotalInvAmt,TotalInvQty) = "
|
||||
// select
|
||||
+ "(SELECT currencyConvert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID),"
|
||||
+ " currencyConvert(il.LineNetAmt,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID),il.QtyInvoiced "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND pc.M_Product_ID=il.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND ROWNUM=1"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND i.C_Invoice_ID=")
|
||||
.append(get_ID()).append(") ")
|
||||
// update
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND pc.M_Product_ID=il.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND i.C_Invoice_ID=")
|
||||
.append(get_ID()).append(")");
|
||||
*/
|
||||
// the next command is equivalent and works in postgresql and oracle
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET (PriceLastInv, TotalInvAmt,TotalInvQty) = "
|
||||
// select
|
||||
+ "(SELECT currencyConvert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID),"
|
||||
+ " currencyConvert(il.LineNetAmt,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID),il.QtyInvoiced "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND il.c_invoiceline_id = (SELECT MIN(C_InvoiceLine_ID) FROM C_InvoiceLine WHERE C_Invoice_ID=")
|
||||
.append(get_ID()).append(")"
|
||||
+ " AND pc.M_Product_ID=il.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND i.C_Invoice_ID=")
|
||||
.append(get_ID()).append(") ")
|
||||
// update
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM C_Invoice i, C_InvoiceLine il, C_AcctSchema a "
|
||||
+ "WHERE i.C_Invoice_ID=il.C_Invoice_ID"
|
||||
+ " AND pc.M_Product_ID=il.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND i.C_Invoice_ID=")
|
||||
.append(get_ID()).append(")");
|
||||
// end globalqss 2005-10-19
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - Updated=" + no);
|
||||
} // updateProductInfo
|
||||
|
||||
} // Doc_Invoice
|
|
@ -0,0 +1,327 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post MatchInv Documents.
|
||||
* <pre>
|
||||
* Table: M_MatchInv (472)
|
||||
* Document Types: MXI
|
||||
* </pre>
|
||||
* Update Costing Records
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_MatchInv.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_MatchInv extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_MatchInv (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super(ass, MMatchInv.class, rs, DOCTYPE_MatMatchInv, trxName);
|
||||
} // Doc_MatchInv
|
||||
|
||||
/** Invoice Line */
|
||||
private MInvoiceLine m_invoiceLine = null;
|
||||
/** Material Receipt */
|
||||
private MInOutLine m_receiptLine = null;
|
||||
|
||||
private ProductCost m_pc = null;
|
||||
|
||||
/** Commitments */
|
||||
private DocLine[] m_commitments = null;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
setC_Currency_ID (Doc.NO_CURRENCY);
|
||||
MMatchInv matchInv = (MMatchInv)getPO();
|
||||
setDateDoc(matchInv.getDateTrx());
|
||||
setQty (matchInv.getQty());
|
||||
// Invoice Info
|
||||
int C_InvoiceLine_ID = matchInv.getC_InvoiceLine_ID();
|
||||
m_invoiceLine = new MInvoiceLine (getCtx(), C_InvoiceLine_ID, null);
|
||||
// BP for NotInvoicedReceipts
|
||||
int C_BPartner_ID = m_invoiceLine.getParent().getC_BPartner_ID();
|
||||
setC_BPartner_ID(C_BPartner_ID);
|
||||
//
|
||||
int M_InOutLine_ID = matchInv.getM_InOutLine_ID();
|
||||
m_receiptLine = new MInOutLine (getCtx(), M_InOutLine_ID, null);
|
||||
//
|
||||
m_pc = new ProductCost (Env.getCtx(),
|
||||
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(), null);
|
||||
m_pc.setQty(getQty());
|
||||
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
return Env.ZERO;
|
||||
} // getBalance
|
||||
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MXI.
|
||||
* (single line)
|
||||
* <pre>
|
||||
* NotInvoicedReceipts DR (Receipt Org)
|
||||
* InventoryClearing CR
|
||||
* InvoicePV DR CR (difference)
|
||||
* Commitment
|
||||
* Expense CR
|
||||
* Offset DR
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
// Nothing to do
|
||||
if (getM_Product_ID() == 0 // no Product
|
||||
|| getQty().signum() == 0
|
||||
|| m_receiptLine.getMovementQty().signum() == 0) // Qty = 0
|
||||
{
|
||||
log.fine("No Product/Qty - M_Product_ID=" + getM_Product_ID()
|
||||
+ ",Qty=" + getQty() + ",InOutQty=" + m_receiptLine.getMovementQty());
|
||||
return facts;
|
||||
}
|
||||
MMatchInv matchInv = (MMatchInv)getPO();
|
||||
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID (as.getC_Currency_ID());
|
||||
|
||||
/** Needs to be handeled in PO Matching as no Receipt info
|
||||
if (m_pc.isService())
|
||||
{
|
||||
log.fine("Service - skipped");
|
||||
return fact;
|
||||
}
|
||||
**/
|
||||
|
||||
|
||||
// NotInvoicedReceipt DR
|
||||
// From Receipt
|
||||
BigDecimal multiplier = getQty()
|
||||
.divide(m_receiptLine.getMovementQty(), 12, BigDecimal.ROUND_HALF_UP)
|
||||
.abs();
|
||||
FactLine dr = fact.createLine (null,
|
||||
getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as),
|
||||
as.getC_Currency_ID(), Env.ONE, null); // updated below
|
||||
if (dr == null)
|
||||
{
|
||||
p_Error = "No Product Costs";
|
||||
return null;
|
||||
}
|
||||
dr.setQty(getQty());
|
||||
// dr.setM_Locator_ID(m_receiptLine.getM_Locator_ID());
|
||||
// MInOut receipt = m_receiptLine.getParent();
|
||||
// dr.setLocationFromBPartner(receipt.getC_BPartner_Location_ID(), true); // from Loc
|
||||
// dr.setLocationFromLocator(m_receiptLine.getM_Locator_ID(), false); // to Loc
|
||||
BigDecimal temp = dr.getAcctBalance();
|
||||
// Set AmtAcctCr/Dr from Receipt (sets also Project)
|
||||
if (!dr.updateReverseLine (MInOut.Table_ID, // Amt updated
|
||||
m_receiptLine.getM_InOut_ID(), m_receiptLine.getM_InOutLine_ID(),
|
||||
multiplier))
|
||||
{
|
||||
p_Error = "Mat.Receipt not posted yet";
|
||||
return null;
|
||||
}
|
||||
log.fine("CR - Amt(" + temp + "->" + dr.getAcctBalance()
|
||||
+ ") - " + dr.toString());
|
||||
|
||||
// InventoryClearing CR
|
||||
// From Invoice
|
||||
MAccount expense = m_pc.getAccount(ProductCost.ACCTTYPE_P_InventoryClearing, as);
|
||||
if (m_pc.isService())
|
||||
expense = m_pc.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
BigDecimal LineNetAmt = m_invoiceLine.getLineNetAmt();
|
||||
multiplier = getQty()
|
||||
.divide(m_invoiceLine.getQtyInvoiced(), 12, BigDecimal.ROUND_HALF_UP)
|
||||
.abs();
|
||||
if (multiplier.compareTo(Env.ONE) != 0)
|
||||
LineNetAmt = LineNetAmt.multiply(multiplier);
|
||||
if (m_pc.isService())
|
||||
LineNetAmt = dr.getAcctBalance(); // book out exact receipt amt
|
||||
FactLine cr = null;
|
||||
if (as.isAccrual())
|
||||
{
|
||||
cr = fact.createLine (null, expense,
|
||||
as.getC_Currency_ID(), null, LineNetAmt); // updated below
|
||||
if (cr == null)
|
||||
{
|
||||
log.fine("Line Net Amt=0 - M_Product_ID=" + getM_Product_ID()
|
||||
+ ",Qty=" + getQty() + ",InOutQty=" + m_receiptLine.getMovementQty());
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
}
|
||||
cr.setQty(getQty().negate());
|
||||
temp = cr.getAcctBalance();
|
||||
// Set AmtAcctCr/Dr from Invoice (sets also Project)
|
||||
if (as.isAccrual() && !cr.updateReverseLine (MInvoice.Table_ID, // Amt updated
|
||||
m_invoiceLine.getC_Invoice_ID(), m_invoiceLine.getC_InvoiceLine_ID(), multiplier))
|
||||
{
|
||||
p_Error = "Invoice not posted yet";
|
||||
return null;
|
||||
}
|
||||
log.fine("DR - Amt(" + temp + "->" + cr.getAcctBalance()
|
||||
+ ") - " + cr.toString());
|
||||
}
|
||||
else // Cash Acct
|
||||
{
|
||||
MInvoice invoice = m_invoiceLine.getParent();
|
||||
if (as.getC_Currency_ID() == invoice.getC_Currency_ID())
|
||||
LineNetAmt = MConversionRate.convert(getCtx(), LineNetAmt,
|
||||
invoice.getC_Currency_ID(), as.getC_Currency_ID(),
|
||||
invoice.getDateAcct(), invoice.getC_ConversionType_ID(),
|
||||
invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
|
||||
cr = fact.createLine (null, expense,
|
||||
as.getC_Currency_ID(), null, LineNetAmt);
|
||||
cr.setQty(getQty().multiply(multiplier).negate());
|
||||
}
|
||||
cr.setC_Activity_ID(m_invoiceLine.getC_Activity_ID());
|
||||
cr.setC_Campaign_ID(m_invoiceLine.getC_Campaign_ID());
|
||||
cr.setC_Project_ID(m_invoiceLine.getC_Project_ID());
|
||||
cr.setC_UOM_ID(m_invoiceLine.getC_UOM_ID());
|
||||
cr.setUser1_ID(m_invoiceLine.getUser1_ID());
|
||||
cr.setUser2_ID(m_invoiceLine.getUser2_ID());
|
||||
|
||||
|
||||
// Invoice Price Variance difference
|
||||
BigDecimal ipv = cr.getAcctBalance().add(dr.getAcctBalance()).negate();
|
||||
if (ipv.signum() != 0)
|
||||
{
|
||||
FactLine pv = fact.createLine(null,
|
||||
m_pc.getAccount(ProductCost.ACCTTYPE_P_IPV, as),
|
||||
as.getC_Currency_ID(), ipv);
|
||||
pv.setC_Activity_ID(m_invoiceLine.getC_Activity_ID());
|
||||
pv.setC_Campaign_ID(m_invoiceLine.getC_Campaign_ID());
|
||||
pv.setC_Project_ID(m_invoiceLine.getC_Project_ID());
|
||||
pv.setC_UOM_ID(m_invoiceLine.getC_UOM_ID());
|
||||
pv.setUser1_ID(m_invoiceLine.getUser1_ID());
|
||||
pv.setUser2_ID(m_invoiceLine.getUser2_ID());
|
||||
}
|
||||
log.fine("IPV=" + ipv + "; Balance=" + fact.getSourceBalance());
|
||||
|
||||
// Cost Detail Record - data from Expense/IncClearing (CR) record
|
||||
MCostDetail.createInvoice(as, getAD_Org_ID(),
|
||||
getM_Product_ID(), matchInv.getM_AttributeSetInstance_ID(),
|
||||
m_invoiceLine.getC_InvoiceLine_ID(), 0, // No cost element
|
||||
cr.getAcctBalance().negate(), getQty(), // correcting
|
||||
getDescription(), getTrxName());
|
||||
|
||||
// Update Costing
|
||||
updateProductInfo(as.getC_AcctSchema_ID(),
|
||||
MAcctSchema.COSTINGMETHOD_StandardCosting.equals(as.getCostingMethod()));
|
||||
//
|
||||
facts.add(fact);
|
||||
|
||||
/** Commitment release ****/
|
||||
if (as.isAccrual() && as.isCreateCommitment())
|
||||
{
|
||||
fact = Doc_Order.getCommitmentRelease(as, this,
|
||||
getQty(), m_invoiceLine.getC_InvoiceLine_ID(), Env.ONE);
|
||||
if (fact == null)
|
||||
return null;
|
||||
facts.add(fact);
|
||||
} // Commitment
|
||||
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Update Product Info (old).
|
||||
* - Costing (CostStandardCumQty, CostStandardCumAmt, CostAverageCumQty, CostAverageCumAmt)
|
||||
* @param C_AcctSchema_ID accounting schema
|
||||
* @param standardCosting true if std costing
|
||||
* @return true if updated
|
||||
* @deprecated old costing
|
||||
*/
|
||||
private boolean updateProductInfo (int C_AcctSchema_ID, boolean standardCosting)
|
||||
{
|
||||
log.fine("M_MatchInv_ID=" + get_ID());
|
||||
|
||||
// update Product Costing Qty/Amt
|
||||
// requires existence of currency conversion !!
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET (CostStandardCumQty,CostStandardCumAmt, CostAverageCumQty,CostAverageCumAmt) = "
|
||||
+ "(SELECT pc.CostStandardCumQty + m.Qty,"
|
||||
+ "pc.CostStandardCumAmt + currencyConvert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)*m.Qty, "
|
||||
+ "pc.CostAverageCumQty + m.Qty,"
|
||||
+ "pc.CostAverageCumAmt + currencyConvert(il.PriceActual,i.C_Currency_ID,a.C_Currency_ID,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)*m.Qty "
|
||||
+ "FROM M_MatchInv m"
|
||||
+ " INNER JOIN C_InvoiceLine il ON (m.C_InvoiceLine_ID=il.C_InvoiceLine_ID)"
|
||||
+ " INNER JOIN C_Invoice i ON (il.C_Invoice_ID=i.C_Invoice_ID),"
|
||||
+ " C_AcctSchema a "
|
||||
+ "WHERE pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND pc.M_Product_ID=m.M_Product_ID"
|
||||
+ " AND m.M_MatchInv_ID=").append(get_ID()).append(")"
|
||||
//
|
||||
+ "WHERE pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(
|
||||
" AND EXISTS (SELECT * FROM M_MatchInv m "
|
||||
+ "WHERE pc.M_Product_ID=m.M_Product_ID"
|
||||
+ " AND m.M_MatchInv_ID=").append(get_ID()).append(")");
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - Qty/Amt Updated #=" + no);
|
||||
|
||||
// Update Average Cost
|
||||
sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing "
|
||||
+ "SET CostAverage = CostAverageCumAmt/DECODE(CostAverageCumQty, 0,1, CostAverageCumQty) "
|
||||
+ "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
|
||||
.append(" AND M_Product_ID=").append(getM_Product_ID());
|
||||
no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - AvgCost Updated #=" + no);
|
||||
|
||||
|
||||
// Update Current Cost
|
||||
if (!standardCosting)
|
||||
{
|
||||
sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing "
|
||||
+ "SET CurrentCostPrice = CostAverage "
|
||||
+ "WHERE C_AcctSchema_ID=").append(C_AcctSchema_ID)
|
||||
.append(" AND M_Product_ID=").append(getM_Product_ID());
|
||||
no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - CurrentCost Updated=" + no);
|
||||
}
|
||||
return true;
|
||||
} // updateProductInfo
|
||||
|
||||
} // Doc_MatchInv
|
|
@ -0,0 +1,243 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post MatchPO Documents.
|
||||
* <pre>
|
||||
* Table: C_MatchPO (473)
|
||||
* Document Types: MXP
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_MatchPO.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_MatchPO extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_MatchPO (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super(ass, MMatchPO.class, rs, DOCTYPE_MatMatchPO, trxName);
|
||||
} // Doc_MatchPO
|
||||
|
||||
private int m_C_OrderLine_ID = 0;
|
||||
private MOrderLine m_oLine = null;
|
||||
//
|
||||
private int m_M_InOutLine_ID = 0;
|
||||
private int m_C_InvoiceLine_ID = 0;
|
||||
private ProductCost m_pc;
|
||||
private int m_M_AttributeSetInstance_ID = 0;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
setC_Currency_ID (Doc.NO_CURRENCY);
|
||||
MMatchPO matchPO = (MMatchPO)getPO();
|
||||
setDateDoc(matchPO.getDateTrx());
|
||||
//
|
||||
m_M_AttributeSetInstance_ID = matchPO.getM_AttributeSetInstance_ID();
|
||||
setQty (matchPO.getQty());
|
||||
//
|
||||
m_C_OrderLine_ID = matchPO.getC_OrderLine_ID();
|
||||
m_oLine = new MOrderLine (getCtx(), m_C_OrderLine_ID, getTrxName());
|
||||
//
|
||||
m_M_InOutLine_ID = matchPO.getM_InOutLine_ID();
|
||||
m_C_InvoiceLine_ID = matchPO.getC_InvoiceLine_ID();
|
||||
//
|
||||
m_pc = new ProductCost (Env.getCtx(),
|
||||
getM_Product_ID(), m_M_AttributeSetInstance_ID, getTrxName());
|
||||
m_pc.setQty(getQty());
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return Zero - always balanced
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
return Env.ZERO;
|
||||
} // getBalance
|
||||
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MXP.
|
||||
* <pre>
|
||||
* Product PPV <difference>
|
||||
* PPV_Offset <difference>
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
//
|
||||
if (getM_Product_ID() == 0 // Nothing to do if no Product
|
||||
|| getQty().signum() == 0
|
||||
|| m_M_InOutLine_ID == 0) // No posting if not matched to Shipment
|
||||
{
|
||||
log.fine("No Product/Qty - M_Product_ID=" + getM_Product_ID()
|
||||
+ ",Qty=" + getQty());
|
||||
return facts;
|
||||
}
|
||||
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID(as.getC_Currency_ID());
|
||||
|
||||
// Purchase Order Line
|
||||
BigDecimal poCost = m_oLine.getPriceCost();
|
||||
if (poCost == null || poCost.signum() == 0)
|
||||
poCost = m_oLine.getPriceActual();
|
||||
poCost = poCost.multiply(getQty()); // Delivered so far
|
||||
// Different currency
|
||||
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
|
||||
{
|
||||
MOrder order = m_oLine.getParent();
|
||||
BigDecimal rate = MConversionRate.getRate(
|
||||
order.getC_Currency_ID(), as.getC_Currency_ID(),
|
||||
order.getDateAcct(), order.getC_ConversionType_ID(),
|
||||
m_oLine.getAD_Client_ID(), m_oLine.getAD_Org_ID());
|
||||
if (rate == null)
|
||||
{
|
||||
p_Error = "Purchase Order not convertible - " + as.getName();
|
||||
return null;
|
||||
}
|
||||
poCost = poCost.multiply(rate);
|
||||
if (poCost.scale() > as.getCostingPrecision())
|
||||
poCost = poCost.setScale(as.getCostingPrecision(), BigDecimal.ROUND_HALF_UP);
|
||||
}
|
||||
|
||||
// Create PO Cost Detail Record firs
|
||||
MCostDetail.createOrder(as, m_oLine.getAD_Org_ID(),
|
||||
getM_Product_ID(), m_M_AttributeSetInstance_ID,
|
||||
m_C_OrderLine_ID, 0, // no cost element
|
||||
poCost, getQty(), // Delivered
|
||||
m_oLine.getDescription(), getTrxName());
|
||||
|
||||
// Current Costs
|
||||
String costingMethod = as.getCostingMethod();
|
||||
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
||||
MProductCategoryAcct pca = MProductCategoryAcct.get(getCtx(),
|
||||
product.getM_Product_Category_ID(), as.getC_AcctSchema_ID(), getTrxName());
|
||||
if (pca.getCostingMethod() != null)
|
||||
costingMethod = pca.getCostingMethod();
|
||||
BigDecimal costs = m_pc.getProductCosts(as, getAD_Org_ID(),
|
||||
costingMethod, m_C_OrderLine_ID, false); // non-zero costs
|
||||
|
||||
// No Costs yet - no PPV
|
||||
if (costs == null || costs.signum() == 0)
|
||||
{
|
||||
p_Error = "Resubmit - No Costs for " + product.getName();
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Difference
|
||||
BigDecimal difference = poCost.subtract(costs);
|
||||
// Nothing to post
|
||||
if (difference.signum() == 0)
|
||||
{
|
||||
log.log(Level.FINE, "No Cost Difference for M_Product_ID=" + getM_Product_ID());
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
}
|
||||
|
||||
// Product PPV
|
||||
FactLine cr = fact.createLine(null,
|
||||
m_pc.getAccount(ProductCost.ACCTTYPE_P_PPV, as),
|
||||
as.getC_Currency_ID(), difference);
|
||||
if (cr != null)
|
||||
{
|
||||
cr.setQty(getQty());
|
||||
cr.setC_BPartner_ID(m_oLine.getC_BPartner_ID());
|
||||
cr.setC_Activity_ID(m_oLine.getC_Activity_ID());
|
||||
cr.setC_Campaign_ID(m_oLine.getC_Campaign_ID());
|
||||
cr.setC_Project_ID(m_oLine.getC_Project_ID());
|
||||
cr.setC_UOM_ID(m_oLine.getC_UOM_ID());
|
||||
cr.setUser1_ID(m_oLine.getUser1_ID());
|
||||
cr.setUser2_ID(m_oLine.getUser2_ID());
|
||||
}
|
||||
|
||||
// PPV Offset
|
||||
FactLine dr = fact.createLine(null,
|
||||
getAccount(Doc.ACCTTYPE_PPVOffset, as),
|
||||
as.getC_Currency_ID(), difference.negate());
|
||||
if (dr != null)
|
||||
{
|
||||
dr.setQty(getQty().negate());
|
||||
dr.setC_BPartner_ID(m_oLine.getC_BPartner_ID());
|
||||
dr.setC_Activity_ID(m_oLine.getC_Activity_ID());
|
||||
dr.setC_Campaign_ID(m_oLine.getC_Campaign_ID());
|
||||
dr.setC_Project_ID(m_oLine.getC_Project_ID());
|
||||
dr.setC_UOM_ID(m_oLine.getC_UOM_ID());
|
||||
dr.setUser1_ID(m_oLine.getUser1_ID());
|
||||
dr.setUser2_ID(m_oLine.getUser2_ID());
|
||||
}
|
||||
|
||||
//
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Update Product Info (old).
|
||||
* - Costing (CostStandardPOQty, CostStandardPOAmt)
|
||||
* @param C_AcctSchema_ID accounting schema
|
||||
* @deprecated old costing
|
||||
*/
|
||||
private void updateProductInfo (int C_AcctSchema_ID)
|
||||
{
|
||||
log.fine("M_MatchPO_ID=" + get_ID());
|
||||
|
||||
// update Product Costing
|
||||
// requires existence of currency conversion !!
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET (CostStandardPOQty,CostStandardPOAmt) = "
|
||||
+ "(SELECT CostStandardPOQty + m.Qty,"
|
||||
+ " CostStandardPOAmt + currencyConvert(ol.PriceActual,ol.C_Currency_ID,a.C_Currency_ID,ol.DateOrdered,null,ol.AD_Client_ID,ol.AD_Org_ID)*m.Qty "
|
||||
+ "FROM M_MatchPO m, C_OrderLine ol, C_AcctSchema a "
|
||||
+ "WHERE m.C_OrderLine_ID=ol.C_OrderLine_ID"
|
||||
+ " AND pc.M_Product_ID=ol.M_Product_ID"
|
||||
+ " AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ "AND m.M_MatchPO_ID=").append(get_ID()).append(") ")
|
||||
.append("WHERE pc.C_AcctSchema_ID=").append(C_AcctSchema_ID)
|
||||
.append(" AND pc.M_Product_ID=").append(getM_Product_ID());
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - Updated=" + no);
|
||||
} // updateProductInfo
|
||||
|
||||
} // Doc_MatchPO
|
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: M_Movement (323)
|
||||
* Document Types: MMM
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Movement.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Movement extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
public Doc_Movement (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MMovement.class, rs, DOCTYPE_MatMovement, trxName);
|
||||
} // Doc_Movement
|
||||
|
||||
/**
|
||||
* Load Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID(NO_CURRENCY);
|
||||
MMovement move = (MMovement)getPO();
|
||||
setDateDoc (move.getMovementDate());
|
||||
setDateAcct(move.getMovementDate());
|
||||
// Contained Objects
|
||||
p_lines = loadLines(move);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param move move
|
||||
* @return document lines (DocLine_Material)
|
||||
*/
|
||||
private DocLine[] loadLines(MMovement move)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MMovementLine[] lines = move.getLines(false);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MMovementLine line = lines[i];
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
docLine.setQty(line.getMovementQty(), false);
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size()];
|
||||
list.toArray(dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return balance (ZERO) - always balanced
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MMM.
|
||||
* <pre>
|
||||
* Movement
|
||||
* Inventory DR CR
|
||||
* InventoryTo DR CR
|
||||
* </pre>
|
||||
* @param as account schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID(as.getC_Currency_ID());
|
||||
|
||||
// Line pointers
|
||||
FactLine dr = null;
|
||||
FactLine cr = null;
|
||||
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
|
||||
|
||||
// ** Inventory DR CR
|
||||
dr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), costs.negate()); // from (-) CR
|
||||
if (dr == null)
|
||||
continue;
|
||||
dr.setM_Locator_ID(line.getM_Locator_ID());
|
||||
dr.setQty(line.getQty().negate()); // outgoing
|
||||
|
||||
// ** InventoryTo DR CR
|
||||
cr = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), costs); // to (+) DR
|
||||
if (cr == null)
|
||||
continue;
|
||||
cr.setM_Locator_ID(line.getM_LocatorTo_ID());
|
||||
cr.setQty(line.getQty());
|
||||
|
||||
// Only for between-org movements
|
||||
if (dr.getAD_Org_ID() != cr.getAD_Org_ID())
|
||||
{
|
||||
String costingLevel = as.getCostingLevel();
|
||||
MProductCategoryAcct pca = MProductCategoryAcct.get(getCtx(),
|
||||
line.getProduct().getM_Product_Category_ID(),
|
||||
as.getC_AcctSchema_ID(), getTrxName());
|
||||
if (pca.getCostingLevel() != null)
|
||||
costingLevel = pca.getCostingLevel();
|
||||
if (!MAcctSchema.COSTINGLEVEL_Organization.equals(costingLevel))
|
||||
continue;
|
||||
//
|
||||
String description = line.getDescription();
|
||||
if (description == null)
|
||||
description = "";
|
||||
// Cost Detail From
|
||||
MCostDetail.createMovement(as, dr.getAD_Org_ID(), // locator org
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs.negate(), line.getQty().negate(), true,
|
||||
description + "(|->)", getTrxName());
|
||||
// Cost Detail To
|
||||
MCostDetail.createMovement(as, cr.getAD_Org_ID(), // locator org
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs, line.getQty(), false,
|
||||
description + "(|<-)", getTrxName());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
} // Doc_Movement
|
|
@ -0,0 +1,624 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Order Documents.
|
||||
* <pre>
|
||||
* Table: C_Order (259)
|
||||
* Document Types: SOO, POO
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Order.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Order extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Order (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MOrder.class, rs, null, trxName);
|
||||
} // Doc_Order
|
||||
|
||||
/** Contained Optional Tax Lines */
|
||||
private DocTax[] m_taxes = null;
|
||||
/** Requisitions */
|
||||
private DocLine[] m_requisitions = null;
|
||||
/** Order Currency Precision */
|
||||
private int m_precision = -1;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MOrder order = (MOrder)getPO();
|
||||
setDateDoc(order.getDateOrdered());
|
||||
setIsTaxIncluded(order.isTaxIncluded());
|
||||
// Amounts
|
||||
setAmount(AMTTYPE_Gross, order.getGrandTotal());
|
||||
setAmount(AMTTYPE_Net, order.getTotalLines());
|
||||
setAmount(AMTTYPE_Charge, order.getChargeAmt());
|
||||
|
||||
// Contained Objects
|
||||
m_taxes = loadTaxes();
|
||||
p_lines = loadLines(order);
|
||||
// log.fine( "Lines=" + p_lines.length + ", Taxes=" + m_taxes.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param order order
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(MOrder order)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
MOrderLine[] lines = order.getLines();
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MOrderLine line = lines[i];
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
BigDecimal Qty = line.getQtyOrdered();
|
||||
docLine.setQty(Qty, order.isSOTrx());
|
||||
//
|
||||
BigDecimal PriceActual = line.getPriceActual();
|
||||
BigDecimal PriceCost = null;
|
||||
if (getDocumentType().equals(DOCTYPE_POrder)) // PO
|
||||
PriceCost = line.getPriceCost();
|
||||
BigDecimal LineNetAmt = null;
|
||||
if (PriceCost != null && PriceCost.signum() != 0)
|
||||
LineNetAmt = Qty.multiply(PriceCost);
|
||||
else
|
||||
LineNetAmt = line.getLineNetAmt();
|
||||
docLine.setAmount (LineNetAmt); // DR
|
||||
BigDecimal PriceList = line.getPriceList();
|
||||
int C_Tax_ID = docLine.getC_Tax_ID();
|
||||
// Correct included Tax
|
||||
if (isTaxIncluded() && C_Tax_ID != 0)
|
||||
{
|
||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||
if (!tax.isZeroTax())
|
||||
{
|
||||
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, getStdPrecision());
|
||||
log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
|
||||
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
||||
for (int t = 0; t < m_taxes.length; t++)
|
||||
{
|
||||
if (m_taxes[t].getC_Tax_ID() == C_Tax_ID)
|
||||
{
|
||||
m_taxes[t].addIncludedTax(LineNetAmtTax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, getStdPrecision());
|
||||
PriceList = PriceList.subtract(PriceListTax);
|
||||
}
|
||||
} // correct included Tax
|
||||
|
||||
docLine.setAmount (LineNetAmt, PriceList, Qty);
|
||||
list.add(docLine);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dl = new DocLine[list.size()];
|
||||
list.toArray(dl);
|
||||
return dl;
|
||||
} // loadLines
|
||||
|
||||
|
||||
/**
|
||||
* Load Requisitions
|
||||
* @return requisition lines of Order
|
||||
*/
|
||||
private DocLine[] loadRequisitions ()
|
||||
{
|
||||
MOrder order = (MOrder)getPO();
|
||||
MOrderLine[] oLines = order.getLines();
|
||||
HashMap<Integer,BigDecimal> qtys = new HashMap<Integer,BigDecimal>();
|
||||
for (int i = 0; i < oLines.length; i++)
|
||||
{
|
||||
MOrderLine line = oLines[i];
|
||||
qtys.put(new Integer(line.getC_OrderLine_ID()), line.getQtyOrdered());
|
||||
}
|
||||
//
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
String sql = "SELECT * FROM M_RequisitionLine rl "
|
||||
+ "WHERE EXISTS (SELECT * FROM C_Order o "
|
||||
+ " INNER JOIN C_OrderLine ol ON (o.C_Order_ID=ol.C_Order_ID) "
|
||||
+ "WHERE ol.C_OrderLine_ID=rl.C_OrderLine_ID"
|
||||
+ " AND o.C_Order_ID=?) "
|
||||
+ "ORDER BY rl.C_OrderLine_ID";
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, order.getC_Order_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MRequisitionLine line = new MRequisitionLine (getCtx(), rs, null);
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
// Quantity - not more then OrderLine
|
||||
// Issue: Split of Requisition to multiple POs & different price
|
||||
Integer key = new Integer(line.getC_OrderLine_ID());
|
||||
BigDecimal maxQty = qtys.get(key);
|
||||
BigDecimal Qty = line.getQty().max(maxQty);
|
||||
if (Qty.signum() == 0)
|
||||
continue;
|
||||
docLine.setQty (Qty, false);
|
||||
qtys.put(key, maxQty.subtract(Qty));
|
||||
//
|
||||
BigDecimal PriceActual = line.getPriceActual();
|
||||
BigDecimal LineNetAmt = line.getLineNetAmt();
|
||||
if (line.getQty().compareTo(Qty) != 0)
|
||||
LineNetAmt = PriceActual.multiply(Qty);
|
||||
docLine.setAmount (LineNetAmt); // DR
|
||||
list.add (docLine);
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log (Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size ()];
|
||||
list.toArray (dls);
|
||||
return dls;
|
||||
} // loadRequisitions
|
||||
|
||||
|
||||
/**
|
||||
* Get Currency Precision
|
||||
* @return precision
|
||||
*/
|
||||
private int getStdPrecision()
|
||||
{
|
||||
if (m_precision == -1)
|
||||
m_precision = MCurrency.getStdPrecision(getCtx(), getC_Currency_ID());
|
||||
return m_precision;
|
||||
} // getPrecision
|
||||
|
||||
/**
|
||||
* Load Invoice Taxes
|
||||
* @return DocTax Array
|
||||
*/
|
||||
private DocTax[] loadTaxes()
|
||||
{
|
||||
ArrayList<DocTax> list = new ArrayList<DocTax>();
|
||||
String sql = "SELECT it.C_Tax_ID, t.Name, t.Rate, it.TaxBaseAmt, it.TaxAmt, t.IsSalesTax "
|
||||
+ "FROM C_Tax t, C_OrderTax it "
|
||||
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Order_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, getTrxName());
|
||||
pstmt.setInt(1, get_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
//
|
||||
while (rs.next())
|
||||
{
|
||||
int C_Tax_ID = rs.getInt(1);
|
||||
String name = rs.getString(2);
|
||||
BigDecimal rate = rs.getBigDecimal(3);
|
||||
BigDecimal taxBaseAmt = rs.getBigDecimal(4);
|
||||
BigDecimal amount = rs.getBigDecimal(5);
|
||||
boolean salesTax = "Y".equals(rs.getString(6));
|
||||
//
|
||||
DocTax taxLine = new DocTax(C_Tax_ID, name, rate,
|
||||
taxBaseAmt, amount, salesTax);
|
||||
list.add(taxLine);
|
||||
}
|
||||
//
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocTax[] tl = new DocTax[list.size()];
|
||||
list.toArray(tl);
|
||||
return tl;
|
||||
} // loadTaxes
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total - no rounding
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = new BigDecimal(0.0);
|
||||
StringBuffer sb = new StringBuffer (" [");
|
||||
// Total
|
||||
retValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));
|
||||
sb.append(getAmount(Doc.AMTTYPE_Gross));
|
||||
// - Header Charge
|
||||
retValue = retValue.subtract(getAmount(Doc.AMTTYPE_Charge));
|
||||
sb.append("-").append(getAmount(Doc.AMTTYPE_Charge));
|
||||
// - Tax
|
||||
if (m_taxes != null)
|
||||
{
|
||||
for (int i = 0; i < m_taxes.length; i++)
|
||||
{
|
||||
retValue = retValue.subtract(m_taxes[i].getAmount());
|
||||
sb.append("-").append(m_taxes[i].getAmount());
|
||||
}
|
||||
}
|
||||
// - Lines
|
||||
if (p_lines != null)
|
||||
{
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
retValue = retValue.subtract(p_lines[i].getAmtSource());
|
||||
sb.append("-").append(p_lines[i].getAmtSource());
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
//
|
||||
if (retValue.signum() != 0 // Sum of Cost(vs. Price) in lines may not add up
|
||||
&& getDocumentType().equals(DOCTYPE_POrder)) // PO
|
||||
{
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString() + " (ignored)");
|
||||
retValue = Env.ZERO;
|
||||
}
|
||||
else
|
||||
log.fine(toString() + " Balance=" + retValue + sb.toString());
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Create Facts (the accounting logic) for
|
||||
* SOO, POO.
|
||||
* <pre>
|
||||
* Reservation (release)
|
||||
* Expense DR
|
||||
* Offset CR
|
||||
* Commitment
|
||||
* (to be released by Invoice Matching)
|
||||
* Expense CR
|
||||
* Offset DR
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
// Purchase Order
|
||||
if (getDocumentType().equals(DOCTYPE_POrder))
|
||||
{
|
||||
updateProductPO(as);
|
||||
updateProductInfo(as.getC_AcctSchema_ID());
|
||||
|
||||
BigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);
|
||||
|
||||
// Commitment
|
||||
if (as.isCreateCommitment())
|
||||
{
|
||||
Fact fact = new Fact(this, as, Fact.POST_Commitment);
|
||||
BigDecimal total = Env.ZERO;
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal cost = line.getAmtSource();
|
||||
total = total.add(cost);
|
||||
|
||||
// Account
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
FactLine fl = fact.createLine (line, expense,
|
||||
getC_Currency_ID(), cost, null);
|
||||
}
|
||||
// Offset
|
||||
MAccount offset = getAccount(ACCTTYPE_CommitmentOffset, as);
|
||||
if (offset == null)
|
||||
{
|
||||
p_Error = "@NotFound@ @CommitmentOffset_Acct@";
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
fact.createLine (null, offset,
|
||||
getC_Currency_ID(), null, total);
|
||||
//
|
||||
facts.add(fact);
|
||||
}
|
||||
|
||||
// Reverse Reservation
|
||||
if (as.isCreateReservation())
|
||||
{
|
||||
Fact fact = new Fact(this, as, Fact.POST_Reservation);
|
||||
BigDecimal total = Env.ZERO;
|
||||
if (m_requisitions == null)
|
||||
m_requisitions = loadRequisitions();
|
||||
for (int i = 0; i < m_requisitions.length; i++)
|
||||
{
|
||||
DocLine line = m_requisitions[i];
|
||||
BigDecimal cost = line.getAmtSource();
|
||||
total = total.add(cost);
|
||||
|
||||
// Account
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
FactLine fl = fact.createLine (line, expense,
|
||||
getC_Currency_ID(), null, cost);
|
||||
}
|
||||
// Offset
|
||||
MAccount offset = getAccount(ACCTTYPE_CommitmentOffset, as);
|
||||
if (offset == null)
|
||||
{
|
||||
p_Error = "@NotFound@ @CommitmentOffset_Acct@";
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
fact.createLine (null, offset,
|
||||
getC_Currency_ID(), total, null);
|
||||
//
|
||||
facts.add(fact);
|
||||
} // reservations
|
||||
}
|
||||
// SO
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
|
||||
/**
|
||||
* Update ProductPO PriceLastPO
|
||||
* @param as accounting schema
|
||||
*/
|
||||
private void updateProductPO(MAcctSchema as)
|
||||
{
|
||||
MClientInfo ci = MClientInfo.get(getCtx(), as.getAD_Client_ID());
|
||||
if (ci.getC_AcctSchema1_ID() != as.getC_AcctSchema_ID())
|
||||
return;
|
||||
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_PO po "
|
||||
+ "SET PriceLastPO = (SELECT currencyConvert(ol.PriceActual,ol.C_Currency_ID,po.C_Currency_ID,o.DateOrdered,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) "
|
||||
+ "FROM C_Order o, C_OrderLine ol "
|
||||
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
|
||||
+ " AND po.M_Product_ID=ol.M_Product_ID AND po.C_BPartner_ID=o.C_BPartner_ID"
|
||||
+ " AND ROWNUM=1 AND o.C_Order_ID=").append(get_ID()).append(") ")
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM C_Order o, C_OrderLine ol "
|
||||
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
|
||||
+ " AND po.M_Product_ID=ol.M_Product_ID AND po.C_BPartner_ID=o.C_BPartner_ID"
|
||||
+ " AND o.C_Order_ID=").append(get_ID()).append(")");
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("Updated=" + no);
|
||||
} // updateProductPO
|
||||
|
||||
|
||||
/**
|
||||
* Get Commitments
|
||||
* @param doc document
|
||||
* @param maxQty Qty invoiced/matched
|
||||
* @param C_InvoiceLine_ID invoice line
|
||||
* @return commitments (order lines)
|
||||
*/
|
||||
protected static DocLine[] getCommitments(Doc doc, BigDecimal maxQty, int C_InvoiceLine_ID)
|
||||
{
|
||||
int precision = -1;
|
||||
//
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
String sql = "SELECT * FROM C_OrderLine ol "
|
||||
+ "WHERE EXISTS "
|
||||
+ "(SELECT * FROM C_InvoiceLine il "
|
||||
+ "WHERE il.C_OrderLine_ID=ol.C_OrderLine_ID"
|
||||
+ " AND il.C_InvoiceLine_ID=?)"
|
||||
+ " OR EXISTS "
|
||||
+ "(SELECT * FROM M_MatchPO po "
|
||||
+ "WHERE po.C_OrderLine_ID=ol.C_OrderLine_ID"
|
||||
+ " AND po.C_InvoiceLine_ID=?)";
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, C_InvoiceLine_ID);
|
||||
pstmt.setInt (2, C_InvoiceLine_ID);
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
if (maxQty.signum() == 0)
|
||||
continue;
|
||||
MOrderLine line = new MOrderLine (doc.getCtx(), rs, null);
|
||||
DocLine docLine = new DocLine (line, doc);
|
||||
// Currency
|
||||
if (precision == -1)
|
||||
{
|
||||
doc.setC_Currency_ID(docLine.getC_Currency_ID());
|
||||
precision = MCurrency.getStdPrecision(doc.getCtx(), docLine.getC_Currency_ID());
|
||||
}
|
||||
// Qty
|
||||
BigDecimal Qty = line.getQtyOrdered().max(maxQty);
|
||||
docLine.setQty(Qty, false);
|
||||
//
|
||||
BigDecimal PriceActual = line.getPriceActual();
|
||||
BigDecimal PriceCost = line.getPriceCost();
|
||||
BigDecimal LineNetAmt = null;
|
||||
if (PriceCost != null && PriceCost.signum() != 0)
|
||||
LineNetAmt = Qty.multiply(PriceCost);
|
||||
else if (Qty.equals(maxQty))
|
||||
LineNetAmt = line.getLineNetAmt();
|
||||
else
|
||||
LineNetAmt = Qty.multiply(PriceActual);
|
||||
maxQty = maxQty.subtract(Qty);
|
||||
|
||||
docLine.setAmount (LineNetAmt); // DR
|
||||
BigDecimal PriceList = line.getPriceList();
|
||||
int C_Tax_ID = docLine.getC_Tax_ID();
|
||||
// Correct included Tax
|
||||
if (C_Tax_ID != 0 && line.getParent().isTaxIncluded())
|
||||
{
|
||||
MTax tax = MTax.get(doc.getCtx(), C_Tax_ID);
|
||||
if (!tax.isZeroTax())
|
||||
{
|
||||
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, precision);
|
||||
s_log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
|
||||
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
||||
BigDecimal PriceListTax = tax.calculateTax(PriceList, true, precision);
|
||||
PriceList = PriceList.subtract(PriceListTax);
|
||||
}
|
||||
} // correct included Tax
|
||||
|
||||
docLine.setAmount (LineNetAmt, PriceList, Qty);
|
||||
list.add(docLine);
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
s_log.log (Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
// Return Array
|
||||
DocLine[] dl = new DocLine[list.size()];
|
||||
list.toArray(dl);
|
||||
return dl;
|
||||
} // getCommitments
|
||||
|
||||
/**
|
||||
* Get Commitment Release.
|
||||
* Called from MatchInv for accrual and Allocation for Cash Based
|
||||
* @param as accounting schema
|
||||
* @param doc doc
|
||||
* @param Qty qty invoiced/matched
|
||||
* @param C_InvoiceLine_ID line
|
||||
* @param multiplier 1 for accrual
|
||||
* @return Fact
|
||||
*/
|
||||
protected static Fact getCommitmentRelease(MAcctSchema as, Doc doc,
|
||||
BigDecimal Qty, int C_InvoiceLine_ID, BigDecimal multiplier)
|
||||
{
|
||||
Fact fact = new Fact(doc, as, Fact.POST_Commitment);
|
||||
DocLine[] commitments = Doc_Order.getCommitments(doc, Qty,
|
||||
C_InvoiceLine_ID);
|
||||
|
||||
BigDecimal total = Env.ZERO;
|
||||
int C_Currency_ID = -1;
|
||||
for (int i = 0; i < commitments.length; i++)
|
||||
{
|
||||
DocLine line = commitments[i];
|
||||
if (C_Currency_ID == -1)
|
||||
C_Currency_ID = line.getC_Currency_ID();
|
||||
else if (C_Currency_ID != line.getC_Currency_ID())
|
||||
{
|
||||
doc.p_Error = "Different Currencies of Order Lines";
|
||||
s_log.log(Level.SEVERE, doc.p_Error);
|
||||
return null;
|
||||
}
|
||||
BigDecimal cost = line.getAmtSource().multiply(multiplier);
|
||||
total = total.add(cost);
|
||||
|
||||
// Account
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
FactLine fl = fact.createLine (line, expense,
|
||||
C_Currency_ID, null, cost);
|
||||
}
|
||||
// Offset
|
||||
MAccount offset = doc.getAccount(ACCTTYPE_CommitmentOffset, as);
|
||||
if (offset == null)
|
||||
{
|
||||
doc.p_Error = "@NotFound@ @CommitmentOffset_Acct@";
|
||||
s_log.log(Level.SEVERE, doc.p_Error);
|
||||
return null;
|
||||
}
|
||||
fact.createLine (null, offset,
|
||||
C_Currency_ID, total, null);
|
||||
return fact;
|
||||
} // getCommitmentRelease
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Update Product Info (old)
|
||||
* - Costing (PriceLastPO)
|
||||
* - PO (PriceLastPO)
|
||||
* @param C_AcctSchema_ID accounting schema
|
||||
* @deprecated old costing
|
||||
*/
|
||||
private void updateProductInfo (int C_AcctSchema_ID)
|
||||
{
|
||||
log.fine("C_Order_ID=" + get_ID());
|
||||
|
||||
/** @todo Last.. would need to compare document/last updated date
|
||||
* would need to maintain LastPriceUpdateDate on _PO and _Costing */
|
||||
|
||||
// update Product Costing
|
||||
// requires existence of currency conversion !!
|
||||
// if there are multiple lines of the same product last price uses first
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"UPDATE M_Product_Costing pc "
|
||||
+ "SET PriceLastPO = "
|
||||
+ "(SELECT currencyConvert(ol.PriceActual,ol.C_Currency_ID,a.C_Currency_ID,o.DateOrdered,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) "
|
||||
+ "FROM C_Order o, C_OrderLine ol, C_AcctSchema a "
|
||||
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
|
||||
+ " AND pc.M_Product_ID=ol.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND ROWNUM=1"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND o.C_Order_ID=")
|
||||
.append(get_ID()).append(") ")
|
||||
.append("WHERE EXISTS (SELECT * "
|
||||
+ "FROM C_Order o, C_OrderLine ol, C_AcctSchema a "
|
||||
+ "WHERE o.C_Order_ID=ol.C_Order_ID"
|
||||
+ " AND pc.M_Product_ID=ol.M_Product_ID AND pc.C_AcctSchema_ID=a.C_AcctSchema_ID"
|
||||
+ " AND pc.C_AcctSchema_ID=").append(C_AcctSchema_ID).append(" AND o.C_Order_ID=")
|
||||
.append(get_ID()).append(")");
|
||||
int no = DB.executeUpdate(sql.toString(), getTrxName());
|
||||
log.fine("M_Product_Costing - Updated=" + no);
|
||||
} // updateProductInfo
|
||||
|
||||
} // Doc_Order
|
|
@ -0,0 +1,183 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: C_Payment (335)
|
||||
* Document Types ARP, APP
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Payment.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Payment extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Payment (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MPayment.class, rs, null, trxName);
|
||||
} // Doc_Payment
|
||||
|
||||
/** Tender Type */
|
||||
private String m_TenderType = null;
|
||||
/** Prepayment */
|
||||
private boolean m_Prepayment = false;
|
||||
/** Bank Account */
|
||||
private int m_C_BankAccount_ID = 0;
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
MPayment pay = (MPayment)getPO();
|
||||
setDateDoc(pay.getDateTrx());
|
||||
m_TenderType = pay.getTenderType();
|
||||
m_Prepayment = pay.isPrepayment();
|
||||
m_C_BankAccount_ID = pay.getC_BankAccount_ID();
|
||||
// Amount
|
||||
setAmount(Doc.AMTTYPE_Gross, pay.getPayAmt());
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Source Currency Balance - always zero
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
// log.config( toString() + " Balance=" + retValue);
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* ARP, APP.
|
||||
* <pre>
|
||||
* ARP
|
||||
* BankInTransit DR
|
||||
* UnallocatedCash CR
|
||||
* or Charge/C_Prepayment
|
||||
* APP
|
||||
* PaymentSelect DR
|
||||
* or Charge/V_Prepayment
|
||||
* BankInTransit CR
|
||||
* CashBankTransfer
|
||||
* -
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
// Cash Transfer
|
||||
if ("X".equals(m_TenderType))
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
}
|
||||
|
||||
int AD_Org_ID = getBank_Org_ID(); // Bank Account Org
|
||||
if (getDocumentType().equals(DOCTYPE_ARReceipt))
|
||||
{
|
||||
// Asset
|
||||
FactLine fl = fact.createLine(null, getAccount(Doc.ACCTTYPE_BankInTransit, as),
|
||||
getC_Currency_ID(), getAmount(), null);
|
||||
if (fl != null && AD_Org_ID != 0)
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
//
|
||||
MAccount acct = null;
|
||||
if (getC_Charge_ID() != 0)
|
||||
acct = MCharge.getAccount(getC_Charge_ID(), as, getAmount());
|
||||
else if (m_Prepayment)
|
||||
acct = getAccount(Doc.ACCTTYPE_C_Prepayment, as);
|
||||
else
|
||||
acct = getAccount(Doc.ACCTTYPE_UnallocatedCash, as);
|
||||
fl = fact.createLine(null, acct,
|
||||
getC_Currency_ID(), null, getAmount());
|
||||
if (fl != null && AD_Org_ID != 0
|
||||
&& getC_Charge_ID() == 0) // don't overwrite charge
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
}
|
||||
// APP
|
||||
else if (getDocumentType().equals(DOCTYPE_APPayment))
|
||||
{
|
||||
MAccount acct = null;
|
||||
if (getC_Charge_ID() != 0)
|
||||
acct = MCharge.getAccount(getC_Charge_ID(), as, getAmount());
|
||||
else if (m_Prepayment)
|
||||
acct = getAccount(Doc.ACCTTYPE_V_Prepayment, as);
|
||||
else
|
||||
acct = getAccount(Doc.ACCTTYPE_PaymentSelect, as);
|
||||
FactLine fl = fact.createLine(null, acct,
|
||||
getC_Currency_ID(), getAmount(), null);
|
||||
if (fl != null && AD_Org_ID != 0
|
||||
&& getC_Charge_ID() == 0) // don't overwrite charge
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
|
||||
// Asset
|
||||
fl = fact.createLine(null, getAccount(Doc.ACCTTYPE_BankInTransit, as),
|
||||
getC_Currency_ID(), null, getAmount());
|
||||
if (fl != null && AD_Org_ID != 0)
|
||||
fl.setAD_Org_ID(AD_Org_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_Error = "DocumentType unknown: " + getDocumentType();
|
||||
log.log(Level.SEVERE, p_Error);
|
||||
fact = null;
|
||||
}
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Get AD_Org_ID from Bank Account
|
||||
* @return AD_Org_ID or 0
|
||||
*/
|
||||
private int getBank_Org_ID ()
|
||||
{
|
||||
if (m_C_BankAccount_ID == 0)
|
||||
return 0;
|
||||
//
|
||||
MBankAccount ba = MBankAccount.get(getCtx(), m_C_BankAccount_ID);
|
||||
return ba.getAD_Org_ID();
|
||||
} // getBank_Org_ID
|
||||
|
||||
} // Doc_Payment
|
|
@ -0,0 +1,216 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Invoice Documents.
|
||||
* <pre>
|
||||
* Table: M_Production (325)
|
||||
* Document Types: MMP
|
||||
* </pre>
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Production.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Production extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
public Doc_Production (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, X_M_Production.class, rs, DOCTYPE_MatProduction, trxName);
|
||||
} // Doc_Production
|
||||
|
||||
/**
|
||||
* Load Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID (NO_CURRENCY);
|
||||
X_M_Production prod = (X_M_Production)getPO();
|
||||
setDateDoc (prod.getMovementDate());
|
||||
setDateAcct(prod.getMovementDate());
|
||||
// Contained Objects
|
||||
p_lines = loadLines(prod);
|
||||
log.fine("Lines=" + p_lines.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Invoice Line
|
||||
* @param prod production
|
||||
* @return DoaLine Array
|
||||
*/
|
||||
private DocLine[] loadLines(X_M_Production prod)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine>();
|
||||
// Production
|
||||
// -- ProductionPlan
|
||||
// -- -- ProductionLine - the real level
|
||||
String sqlPP = "SELECT * FROM M_ProductionPlan pp "
|
||||
+ "WHERE pp.M_Production_ID=? "
|
||||
+ "ORDER BY pp.Line";
|
||||
String sqlPL = "SELECT * FROM M_ProductionLine pl "
|
||||
+ "WHERE pl.M_ProductionPlan_ID=? "
|
||||
+ "ORDER BY pl.Line";
|
||||
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmtPP = DB.prepareStatement(sqlPP, getTrxName());
|
||||
pstmtPP.setInt(1, get_ID());
|
||||
ResultSet rsPP = pstmtPP.executeQuery();
|
||||
//
|
||||
while (rsPP.next())
|
||||
{
|
||||
int M_Product_ID = rsPP.getInt("M_Product_ID");
|
||||
int M_ProductionPlan_ID = rsPP.getInt("M_ProductionPlan_ID");
|
||||
//
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmtPL = DB.prepareStatement(sqlPL, getTrxName());
|
||||
pstmtPL.setInt(1, M_ProductionPlan_ID);
|
||||
ResultSet rsPL = pstmtPL.executeQuery();
|
||||
while (rsPL.next())
|
||||
{
|
||||
X_M_ProductionLine line = new X_M_ProductionLine(getCtx(), rsPL, getTrxName());
|
||||
if (line.getMovementQty().signum() == 0)
|
||||
{
|
||||
log.info("LineQty=0 - " + line);
|
||||
continue;
|
||||
}
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
docLine.setQty (line.getMovementQty(), false);
|
||||
// Identify finished BOM Product
|
||||
docLine.setProductionBOM(line.getM_Product_ID() == M_Product_ID);
|
||||
//
|
||||
log.fine(docLine.toString());
|
||||
list.add (docLine);
|
||||
}
|
||||
rsPL.close();
|
||||
pstmtPL.close();
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
log.log(Level.SEVERE, sqlPL, ee);
|
||||
}
|
||||
}
|
||||
rsPP.close();
|
||||
pstmtPP.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sqlPP, e);
|
||||
}
|
||||
// Return Array
|
||||
DocLine[] dl = new DocLine[list.size()];
|
||||
list.toArray(dl);
|
||||
return dl;
|
||||
} // loadLines
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* MMP.
|
||||
* <pre>
|
||||
* Production
|
||||
* Inventory DR CR
|
||||
* </pre>
|
||||
* @param as account schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID (as.getC_Currency_ID());
|
||||
|
||||
// Line pointer
|
||||
FactLine fl = null;
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
// Calculate Costs
|
||||
BigDecimal costs = null;
|
||||
if (line.isProductionBOM())
|
||||
{
|
||||
// Get BOM Cost - Sum of individual lines
|
||||
BigDecimal bomCost = Env.ZERO;
|
||||
for (int ii = 0; ii < p_lines.length; ii++)
|
||||
{
|
||||
DocLine line0 = p_lines[ii];
|
||||
if (line0.getM_ProductionPlan_ID() != line.getM_ProductionPlan_ID())
|
||||
continue;
|
||||
if (!line0.isProductionBOM())
|
||||
bomCost = bomCost.add(line0.getProductCosts(as, line.getAD_Org_ID(), false));
|
||||
}
|
||||
costs = bomCost.negate();
|
||||
}
|
||||
else
|
||||
costs = line.getProductCosts(as, line.getAD_Org_ID(), false);
|
||||
|
||||
// Inventory DR CR
|
||||
fl = fact.createLine(line,
|
||||
line.getAccount(ProductCost.ACCTTYPE_P_Asset, as),
|
||||
as.getC_Currency_ID(), costs);
|
||||
if (fl == null)
|
||||
{
|
||||
p_Error = "No Costs for Line " + line.getLine() + " - " + line;
|
||||
return null;
|
||||
}
|
||||
fl.setM_Locator_ID(line.getM_Locator_ID());
|
||||
fl.setQty(line.getQty());
|
||||
|
||||
// Cost Detail
|
||||
String description = line.getDescription();
|
||||
if (description == null)
|
||||
description = "";
|
||||
if (line.isProductionBOM())
|
||||
description += "(*)";
|
||||
MCostDetail.createProduction(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
line.get_ID(), 0,
|
||||
costs, line.getQty(),
|
||||
description, getTrxName());
|
||||
}
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
} // Doc_Production
|
|
@ -0,0 +1,221 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Project Issue.
|
||||
* Note:
|
||||
* Will load the default GL Category.
|
||||
* Set up a document type to set the GL Category.
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_ProjectIssue.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_ProjectIssue extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
public Doc_ProjectIssue (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MProjectIssue.class, rs, DOCTYPE_ProjectIssue, trxName);
|
||||
} // Doc_ProjectIssue
|
||||
|
||||
/** Pseudo Line */
|
||||
private DocLine m_line = null;
|
||||
/** Issue */
|
||||
private MProjectIssue m_issue = null;
|
||||
|
||||
/**
|
||||
* Load Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails()
|
||||
{
|
||||
setC_Currency_ID(NO_CURRENCY);
|
||||
m_issue = (MProjectIssue)getPO();
|
||||
setDateDoc (m_issue.getMovementDate());
|
||||
setDateAcct(m_issue.getMovementDate());
|
||||
|
||||
// Pseudo Line
|
||||
m_line = new DocLine (m_issue, this);
|
||||
m_line.setQty (m_issue.getMovementQty(), true); // sets Trx and Storage Qty
|
||||
|
||||
// Pseudo Line Check
|
||||
if (m_line.getM_Product_ID() == 0)
|
||||
log.warning(m_line.toString() + " - No Product");
|
||||
log.fine(m_line.toString());
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Get DocumentNo
|
||||
* @return document no
|
||||
*/
|
||||
public String getDocumentNo ()
|
||||
{
|
||||
MProject p = m_issue.getParent();
|
||||
if (p != null)
|
||||
return p.getValue() + " #" + m_issue.getLine();
|
||||
return "(" + m_issue.get_ID() + ")";
|
||||
} // getDocumentNo
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return Zero (always balanced)
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
BigDecimal retValue = Env.ZERO;
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Create Facts (the accounting logic) for
|
||||
* PJI
|
||||
* <pre>
|
||||
* Issue
|
||||
* ProjectWIP DR
|
||||
* Inventory CR
|
||||
* </pre>
|
||||
* Project Account is either Asset or WIP depending on Project Type
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
// create Fact Header
|
||||
Fact fact = new Fact(this, as, Fact.POST_Actual);
|
||||
setC_Currency_ID (as.getC_Currency_ID());
|
||||
|
||||
MProject project = new MProject (getCtx(), m_issue.getC_Project_ID(), null);
|
||||
String ProjectCategory = project.getProjectCategory();
|
||||
MProduct product = MProduct.get(getCtx(), m_issue.getM_Product_ID());
|
||||
|
||||
// Line pointers
|
||||
FactLine dr = null;
|
||||
FactLine cr = null;
|
||||
|
||||
// Issue Cost
|
||||
BigDecimal cost = null;
|
||||
if (m_issue.getM_InOutLine_ID() != 0)
|
||||
cost = getPOCost(as);
|
||||
else if (m_issue.getS_TimeExpenseLine_ID() != 0)
|
||||
cost = getLaborCost(as);
|
||||
if (cost == null) // standard Product Costs
|
||||
cost = m_line.getProductCosts(as, getAD_Org_ID(), false);
|
||||
|
||||
// Project DR
|
||||
int acctType = ACCTTYPE_ProjectWIP;
|
||||
if (MProject.PROJECTCATEGORY_AssetProject.equals(ProjectCategory))
|
||||
acctType = ACCTTYPE_ProjectAsset;
|
||||
dr = fact.createLine(m_line,
|
||||
getAccount(acctType, as), as.getC_Currency_ID(), cost, null);
|
||||
dr.setQty(m_line.getQty().negate());
|
||||
|
||||
// Inventory CR
|
||||
acctType = ProductCost.ACCTTYPE_P_Asset;
|
||||
if (product.isService())
|
||||
acctType = ProductCost.ACCTTYPE_P_Expense;
|
||||
cr = fact.createLine(m_line,
|
||||
m_line.getAccount(acctType, as),
|
||||
as.getC_Currency_ID(), null, cost);
|
||||
cr.setM_Locator_ID(m_line.getM_Locator_ID());
|
||||
cr.setLocationFromLocator(m_line.getM_Locator_ID(), true); // from Loc
|
||||
//
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
facts.add(fact);
|
||||
return facts;
|
||||
} // createFact
|
||||
|
||||
/**
|
||||
* Get PO Costs in Currency of AcctSchema
|
||||
* @param as Account Schema
|
||||
* @return Unit PO Cost
|
||||
*/
|
||||
private BigDecimal getPOCost(MAcctSchema as)
|
||||
{
|
||||
BigDecimal retValue = null;
|
||||
// Uses PO Date
|
||||
String sql = "SELECT currencyConvert(ol.PriceActual, o.C_Currency_ID, ?, o.DateOrdered, o.C_ConversionType_ID, ?, ?) "
|
||||
+ "FROM C_OrderLine ol"
|
||||
+ " INNER JOIN M_InOutLine iol ON (iol.C_OrderLine_ID=ol.C_OrderLine_ID)"
|
||||
+ " INNER JOIN C_Order o ON (o.C_Order_ID=ol.C_Order_ID) "
|
||||
+ "WHERE iol.M_InOutLine_ID=?";
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, as.getC_Currency_ID());
|
||||
pstmt.setInt(2, getAD_Client_ID());
|
||||
pstmt.setInt(3, getAD_Org_ID());
|
||||
pstmt.setInt(4, m_issue.getM_InOutLine_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
retValue = rs.getBigDecimal(1);
|
||||
log.fine("POCost = " + retValue);
|
||||
}
|
||||
else
|
||||
log.warning("Not found for M_InOutLine_ID=" + m_issue.getM_InOutLine_ID());
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
return retValue;
|
||||
} // getPOCost();
|
||||
|
||||
/**
|
||||
* Get Labor Cost from Expense Report
|
||||
* @param as Account Schema
|
||||
* @return Unit Labor Cost
|
||||
*/
|
||||
private BigDecimal getLaborCost(MAcctSchema as)
|
||||
{
|
||||
BigDecimal retValue = null;
|
||||
|
||||
/** TODO Labor Cost */
|
||||
return retValue;
|
||||
} // getLaborCost
|
||||
|
||||
} // DocProjectIssue
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import java.sql.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Post Order Documents.
|
||||
*
|
||||
* <pre>
|
||||
* Table: M_Requisition
|
||||
* Document Types: POR (Requisition)
|
||||
* </pre>
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Doc_Requisition.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Doc_Requisition extends Doc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ass accounting schemata
|
||||
* @param rs record
|
||||
* @param trxName trx
|
||||
*/
|
||||
protected Doc_Requisition (MAcctSchema[] ass, ResultSet rs, String trxName)
|
||||
{
|
||||
super (ass, MRequisition.class, rs, DOCTYPE_PurchaseRequisition, trxName);
|
||||
} // Doc_Requisition
|
||||
|
||||
/**
|
||||
* Load Specific Document Details
|
||||
* @return error message or null
|
||||
*/
|
||||
protected String loadDocumentDetails ()
|
||||
{
|
||||
setC_Currency_ID(NO_CURRENCY);
|
||||
MRequisition req = (MRequisition)getPO();
|
||||
setDateDoc (req.getDateDoc());
|
||||
setDateAcct (req.getDateDoc());
|
||||
// Amounts
|
||||
setAmount(AMTTYPE_Gross, req.getTotalLines());
|
||||
setAmount(AMTTYPE_Net, req.getTotalLines());
|
||||
// Contained Objects
|
||||
p_lines = loadLines (req);
|
||||
// log.fine( "Lines=" + p_lines.length + ", Taxes=" + m_taxes.length);
|
||||
return null;
|
||||
} // loadDocumentDetails
|
||||
|
||||
/**
|
||||
* Load Requisition Lines
|
||||
* @param req requisition
|
||||
* @return DocLine Array
|
||||
*/
|
||||
private DocLine[] loadLines (MRequisition req)
|
||||
{
|
||||
ArrayList<DocLine> list = new ArrayList<DocLine> ();
|
||||
MRequisitionLine[] lines = req.getLines();
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MRequisitionLine line = lines[i];
|
||||
DocLine docLine = new DocLine (line, this);
|
||||
BigDecimal Qty = line.getQty();
|
||||
docLine.setQty (Qty, false);
|
||||
BigDecimal PriceActual = line.getPriceActual();
|
||||
BigDecimal LineNetAmt = line.getLineNetAmt();
|
||||
docLine.setAmount (LineNetAmt); // DR
|
||||
list.add (docLine);
|
||||
}
|
||||
// Return Array
|
||||
DocLine[] dls = new DocLine[list.size ()];
|
||||
list.toArray (dls);
|
||||
return dls;
|
||||
} // loadLines
|
||||
|
||||
/***************************************************************************
|
||||
* Get Source Currency Balance - subtracts line and tax amounts from total -
|
||||
* no rounding
|
||||
*
|
||||
* @return positive amount, if total invoice is bigger than lines
|
||||
*/
|
||||
public BigDecimal getBalance ()
|
||||
{
|
||||
BigDecimal retValue = new BigDecimal (0.0);
|
||||
return retValue;
|
||||
} // getBalance
|
||||
|
||||
/***************************************************************************
|
||||
* Create Facts (the accounting logic) for POR.
|
||||
* <pre>
|
||||
* Reservation
|
||||
* Expense CR
|
||||
* Offset DR
|
||||
* </pre>
|
||||
* @param as accounting schema
|
||||
* @return Fact
|
||||
*/
|
||||
public ArrayList<Fact> createFacts (MAcctSchema as)
|
||||
{
|
||||
ArrayList<Fact> facts = new ArrayList<Fact>();
|
||||
Fact fact = new Fact (this, as, Fact.POST_Reservation);
|
||||
setC_Currency_ID(as.getC_Currency_ID());
|
||||
//
|
||||
BigDecimal grossAmt = getAmount (Doc.AMTTYPE_Gross);
|
||||
// Commitment
|
||||
if (as.isCreateReservation ())
|
||||
{
|
||||
BigDecimal total = Env.ZERO;
|
||||
for (int i = 0; i < p_lines.length; i++)
|
||||
{
|
||||
DocLine line = p_lines[i];
|
||||
BigDecimal cost = line.getAmtSource();
|
||||
total = total.add (cost);
|
||||
// Account
|
||||
MAccount expense = line.getAccount(ProductCost.ACCTTYPE_P_Expense, as);
|
||||
//
|
||||
fact.createLine (line, expense, as.getC_Currency_ID(), cost, null);
|
||||
}
|
||||
// Offset
|
||||
MAccount offset = getAccount (ACCTTYPE_CommitmentOffset, as);
|
||||
if (offset == null)
|
||||
{
|
||||
p_Error = "@NotFound@ @CommitmentOffset_Acct@";
|
||||
log.log (Level.SEVERE, p_Error);
|
||||
return null;
|
||||
}
|
||||
fact.createLine (null, offset, getC_Currency_ID(), null, total);
|
||||
facts.add(fact);
|
||||
}
|
||||
|
||||
return facts;
|
||||
} // createFact
|
||||
} // Doc_Requisition
|
|
@ -0,0 +1,860 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.util.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Accounting Fact
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Fact.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public final class Fact
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param document pointer to document
|
||||
* @param acctSchema Account Schema to create accounts
|
||||
* @param defaultPostingType the default Posting type (actual,..) for this posting
|
||||
*/
|
||||
public Fact (Doc document, MAcctSchema acctSchema, String defaultPostingType)
|
||||
{
|
||||
m_doc = document;
|
||||
m_acctSchema = acctSchema;
|
||||
m_postingType = defaultPostingType;
|
||||
//
|
||||
log.config(toString());
|
||||
} // Fact
|
||||
|
||||
|
||||
/** Log */
|
||||
private CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
/** Document */
|
||||
private Doc m_doc = null;
|
||||
/** Accounting Schema */
|
||||
private MAcctSchema m_acctSchema = null;
|
||||
/** Transaction */
|
||||
private String m_trxName;
|
||||
|
||||
/** Posting Type */
|
||||
private String m_postingType = null;
|
||||
|
||||
/** Actual Balance Type */
|
||||
public static final String POST_Actual = MFactAcct.POSTINGTYPE_Actual;
|
||||
/** Budget Balance Type */
|
||||
public static final String POST_Budget = MFactAcct.POSTINGTYPE_Budget;;
|
||||
/** Encumbrance Posting */
|
||||
public static final String POST_Commitment = MFactAcct.POSTINGTYPE_Commitment;
|
||||
/** Encumbrance Posting */
|
||||
public static final String POST_Reservation = MFactAcct.POSTINGTYPE_Reservation;
|
||||
|
||||
|
||||
/** Is Converted */
|
||||
private boolean m_converted = false;
|
||||
|
||||
/** Lines */
|
||||
private ArrayList<FactLine> m_lines = new ArrayList<FactLine>();
|
||||
|
||||
|
||||
/**
|
||||
* Dispose
|
||||
*/
|
||||
public void dispose()
|
||||
{
|
||||
m_lines.clear();
|
||||
m_lines = null;
|
||||
} // dispose
|
||||
|
||||
/**
|
||||
* Create and convert Fact Line.
|
||||
* Used to create a DR and/or CR entry
|
||||
*
|
||||
* @param docLine the document line or null
|
||||
* @param account if null, line is not created
|
||||
* @param C_Currency_ID the currency
|
||||
* @param debitAmt debit amount, can be null
|
||||
* @param creditAmt credit amount, can be null
|
||||
* @return Fact Line
|
||||
*/
|
||||
public FactLine createLine (DocLine docLine, MAccount account,
|
||||
int C_Currency_ID, BigDecimal debitAmt, BigDecimal creditAmt)
|
||||
{
|
||||
// log.fine("createLine - " + account + " - Dr=" + debitAmt + ", Cr=" + creditAmt);
|
||||
|
||||
// Data Check
|
||||
if (account == null)
|
||||
{
|
||||
log.info("No account for " + docLine
|
||||
+ ": Amt=" + debitAmt + "/" + creditAmt
|
||||
+ " - " + toString());
|
||||
return null;
|
||||
}
|
||||
//
|
||||
FactLine line = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
|
||||
m_doc.get_ID(),
|
||||
docLine == null ? 0 : docLine.get_ID(), m_trxName);
|
||||
// Set Info & Account
|
||||
line.setDocumentInfo(m_doc, docLine);
|
||||
line.setPostingType(m_postingType);
|
||||
line.setAccount(m_acctSchema, account);
|
||||
|
||||
// Amounts - one needs to not zero
|
||||
if (!line.setAmtSource(C_Currency_ID, debitAmt, creditAmt))
|
||||
{
|
||||
if (docLine == null || docLine.getQty() == null || docLine.getQty().signum() == 0)
|
||||
{
|
||||
log.fine("Both amounts & qty = 0/Null - " + docLine
|
||||
+ " - " + toString());
|
||||
return null;
|
||||
}
|
||||
log.fine("Both amounts = 0/Null, Qty=" + docLine.getQty() + " - " + docLine
|
||||
+ " - " + toString());
|
||||
}
|
||||
// Convert
|
||||
line.convert();
|
||||
// Optionally overwrite Acct Amount
|
||||
if (docLine != null
|
||||
&& (docLine.getAmtAcctDr() != null || docLine.getAmtAcctCr() != null))
|
||||
line.setAmtAcct(docLine.getAmtAcctDr(), docLine.getAmtAcctCr());
|
||||
//
|
||||
log.fine(line.toString());
|
||||
add(line);
|
||||
return line;
|
||||
} // createLine
|
||||
|
||||
/**
|
||||
* Add Fact Line
|
||||
* @param line fact line
|
||||
*/
|
||||
void add (FactLine line)
|
||||
{
|
||||
m_lines.add(line);
|
||||
} // add
|
||||
|
||||
/**
|
||||
* Create and convert Fact Line.
|
||||
* Used to create either a DR or CR entry
|
||||
*
|
||||
* @param docLine Document Line or null
|
||||
* @param accountDr Account to be used if Amt is DR balance
|
||||
* @param accountCr Account to be used if Amt is CR balance
|
||||
* @param C_Currency_ID Currency
|
||||
* @param Amt if negative Cr else Dr
|
||||
* @return FactLine
|
||||
*/
|
||||
public FactLine createLine (DocLine docLine, MAccount accountDr, MAccount accountCr,
|
||||
int C_Currency_ID, BigDecimal Amt)
|
||||
{
|
||||
if (Amt.signum() < 0)
|
||||
return createLine (docLine, accountCr, C_Currency_ID, null, Amt.abs());
|
||||
else
|
||||
return createLine (docLine, accountDr, C_Currency_ID, Amt, null);
|
||||
} // createLine
|
||||
|
||||
/**
|
||||
* Create and convert Fact Line.
|
||||
* Used to create either a DR or CR entry
|
||||
*
|
||||
* @param docLine Document line or null
|
||||
* @param account Account to be used
|
||||
* @param C_Currency_ID Currency
|
||||
* @param Amt if negative Cr else Dr
|
||||
* @return FactLine
|
||||
*/
|
||||
public FactLine createLine (DocLine docLine, MAccount account,
|
||||
int C_Currency_ID, BigDecimal Amt)
|
||||
{
|
||||
if (Amt.signum() < 0)
|
||||
return createLine (docLine, account, C_Currency_ID, null, Amt.abs());
|
||||
else
|
||||
return createLine (docLine, account, C_Currency_ID, Amt, null);
|
||||
} // createLine
|
||||
|
||||
/**
|
||||
* Is Posting Type
|
||||
* @param PostingType - see POST_*
|
||||
* @return true if document is posting type
|
||||
*/
|
||||
public boolean isPostingType (String PostingType)
|
||||
{
|
||||
return m_postingType.equals(PostingType);
|
||||
} // isPostingType
|
||||
|
||||
/**
|
||||
* Is converted
|
||||
* @return true if converted
|
||||
*/
|
||||
public boolean isConverted()
|
||||
{
|
||||
return m_converted;
|
||||
} // isConverted
|
||||
|
||||
/**
|
||||
* Get AcctSchema
|
||||
* @return AcctSchema
|
||||
*/
|
||||
public MAcctSchema getAcctSchema()
|
||||
{
|
||||
return m_acctSchema;
|
||||
} // getAcctSchema
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Are the lines Source Balanced
|
||||
* @return true if source lines balanced
|
||||
*/
|
||||
public boolean isSourceBalanced()
|
||||
{
|
||||
// No lines -> balanded
|
||||
if (m_lines.size() == 0)
|
||||
return true;
|
||||
BigDecimal balance = getSourceBalance();
|
||||
boolean retValue = balance.signum() == 0;
|
||||
if (retValue)
|
||||
log.finer(toString());
|
||||
else
|
||||
log.warning ("NO - Diff=" + balance + " - " + toString());
|
||||
return retValue;
|
||||
} // isSourceBalanced
|
||||
|
||||
/**
|
||||
* Return Source Balance
|
||||
* @return source balance
|
||||
*/
|
||||
protected BigDecimal getSourceBalance()
|
||||
{
|
||||
BigDecimal result = Env.ZERO;
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine line = (FactLine)m_lines.get(i);
|
||||
result = result.add (line.getSourceBalance());
|
||||
}
|
||||
// log.fine("getSourceBalance - " + result.toString());
|
||||
return result;
|
||||
} // getSourceBalance
|
||||
|
||||
/**
|
||||
* Create Source Line for Suspense Balancing.
|
||||
* Only if Suspense Balancing is enabled and not a multi-currency document
|
||||
* (double check as otherwise the rule should not have fired)
|
||||
* If not balanced create balancing entry in currency of the document
|
||||
* @return FactLine
|
||||
*/
|
||||
public FactLine balanceSource()
|
||||
{
|
||||
if (!m_acctSchema.isSuspenseBalancing() || m_doc.isMultiCurrency())
|
||||
return null;
|
||||
BigDecimal diff = getSourceBalance();
|
||||
log.finer("Diff=" + diff);
|
||||
|
||||
// new line
|
||||
FactLine line = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
|
||||
m_doc.get_ID(), 0, m_trxName);
|
||||
line.setDocumentInfo(m_doc, null);
|
||||
line.setPostingType(m_postingType);
|
||||
|
||||
// Amount
|
||||
if (diff.signum() < 0) // negative balance => DR
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), diff.abs(), Env.ZERO);
|
||||
else // positive balance => CR
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), Env.ZERO, diff);
|
||||
|
||||
// Account
|
||||
line.setAccount(m_acctSchema, m_acctSchema.getSuspenseBalancing_Acct());
|
||||
|
||||
// Convert
|
||||
line.convert();
|
||||
//
|
||||
log.fine(line.toString());
|
||||
m_lines.add(line);
|
||||
return line;
|
||||
} // balancingSource
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Are all segments balanced
|
||||
* @return true if segments are balanced
|
||||
*/
|
||||
public boolean isSegmentBalanced()
|
||||
{
|
||||
if (m_lines.size() == 0)
|
||||
return true;
|
||||
|
||||
MAcctSchemaElement[] elements = m_acctSchema.getAcctSchemaElements();
|
||||
// check all balancing segments
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
{
|
||||
MAcctSchemaElement ase = elements[i];
|
||||
if (ase.isBalanced() && !isSegmentBalanced (ase.getElementType()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // isSegmentBalanced
|
||||
|
||||
/**
|
||||
* Is Source Segment balanced.
|
||||
* @param segmentType - see AcctSchemaElement.SEGMENT_*
|
||||
* Implemented only for Org
|
||||
* Other sensible candidates are Project, User1/2
|
||||
* @return true if segments are balanced
|
||||
*/
|
||||
public boolean isSegmentBalanced (String segmentType)
|
||||
{
|
||||
if (segmentType.equals(MAcctSchemaElement.ELEMENTTYPE_Organization))
|
||||
{
|
||||
HashMap<Integer,BigDecimal> map = new HashMap<Integer,BigDecimal>();
|
||||
// Add up values by key
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine line = (FactLine)m_lines.get(i);
|
||||
Integer key = new Integer(line.getAD_Org_ID());
|
||||
BigDecimal bal = line.getSourceBalance();
|
||||
BigDecimal oldBal = (BigDecimal)map.get(key);
|
||||
if (oldBal != null)
|
||||
bal = bal.add(oldBal);
|
||||
map.put(key, bal);
|
||||
// System.out.println("Add Key=" + key + ", Bal=" + bal + " <- " + line);
|
||||
}
|
||||
// check if all keys are zero
|
||||
Iterator values = map.values().iterator();
|
||||
while (values.hasNext())
|
||||
{
|
||||
BigDecimal bal = (BigDecimal)values.next();
|
||||
if (bal.signum() != 0)
|
||||
{
|
||||
map.clear();
|
||||
log.warning ("(" + segmentType + ") NO - " + toString() + ", Balance=" + bal);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
map.clear();
|
||||
log.finer("(" + segmentType + ") - " + toString());
|
||||
return true;
|
||||
}
|
||||
log.finer("(" + segmentType + ") (not checked) - " + toString());
|
||||
return true;
|
||||
} // isSegmentBalanced
|
||||
|
||||
/**
|
||||
* Balance all segments.
|
||||
* - For all balancing segments
|
||||
* - For all segment values
|
||||
* - If balance <> 0 create dueTo/dueFrom line
|
||||
* overwriting the segment value
|
||||
*/
|
||||
public void balanceSegments()
|
||||
{
|
||||
MAcctSchemaElement[] elements = m_acctSchema.getAcctSchemaElements();
|
||||
// check all balancing segments
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
{
|
||||
MAcctSchemaElement ase = elements[i];
|
||||
if (ase.isBalanced())
|
||||
balanceSegment (ase.getElementType());
|
||||
}
|
||||
} // balanceSegments
|
||||
|
||||
/**
|
||||
* Balance Source Segment
|
||||
* @param elementType segment element type
|
||||
*/
|
||||
private void balanceSegment (String elementType)
|
||||
{
|
||||
// no lines -> balanced
|
||||
if (m_lines.size() == 0)
|
||||
return;
|
||||
|
||||
log.fine ("(" + elementType + ") - " + toString());
|
||||
|
||||
// Org
|
||||
if (elementType.equals(MAcctSchemaElement.ELEMENTTYPE_Organization))
|
||||
{
|
||||
HashMap<Integer,Balance> map = new HashMap<Integer,Balance>();
|
||||
// Add up values by key
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine line = (FactLine)m_lines.get(i);
|
||||
Integer key = new Integer(line.getAD_Org_ID());
|
||||
// BigDecimal balance = line.getSourceBalance();
|
||||
Balance oldBalance = (Balance)map.get(key);
|
||||
if (oldBalance == null)
|
||||
{
|
||||
oldBalance = new Balance (line.getAmtSourceDr(), line.getAmtSourceCr());
|
||||
map.put(key, oldBalance);
|
||||
}
|
||||
else
|
||||
oldBalance.add(line.getAmtSourceDr(), line.getAmtSourceCr());
|
||||
// log.info ("Key=" + key + ", Balance=" + balance + " - " + line);
|
||||
}
|
||||
|
||||
// Create entry for non-zero element
|
||||
Iterator keys = map.keySet().iterator();
|
||||
while (keys.hasNext())
|
||||
{
|
||||
Integer key = (Integer)keys.next();
|
||||
Balance difference = (Balance)map.get(key);
|
||||
log.info (elementType + "=" + key + ", " + difference);
|
||||
//
|
||||
if (!difference.isZeroBalance())
|
||||
{
|
||||
// Create Balancing Entry
|
||||
FactLine line = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
|
||||
m_doc.get_ID(), 0, m_trxName);
|
||||
line.setDocumentInfo(m_doc, null);
|
||||
line.setPostingType(m_postingType);
|
||||
// Amount & Account
|
||||
if (difference.getBalance().signum() < 0)
|
||||
{
|
||||
if (difference.isReversal())
|
||||
{
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), Env.ZERO, difference.getPostBalance());
|
||||
line.setAccount(m_acctSchema, m_acctSchema.getDueTo_Acct(elementType));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), difference.getPostBalance(), Env.ZERO);
|
||||
line.setAccount(m_acctSchema, m_acctSchema.getDueFrom_Acct(elementType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (difference.isReversal())
|
||||
{
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), difference.getPostBalance(), Env.ZERO);
|
||||
line.setAccount(m_acctSchema, m_acctSchema.getDueFrom_Acct(elementType));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), Env.ZERO, difference.getPostBalance());
|
||||
line.setAccount(m_acctSchema, m_acctSchema.getDueTo_Acct(elementType));
|
||||
}
|
||||
}
|
||||
line.convert();
|
||||
line.setAD_Org_ID(key.intValue());
|
||||
//
|
||||
m_lines.add(line);
|
||||
log.fine("(" + elementType + ") - " + line);
|
||||
}
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
} // balanceSegment
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Are the lines Accounting Balanced
|
||||
* @return true if accounting lines are balanced
|
||||
*/
|
||||
public boolean isAcctBalanced()
|
||||
{
|
||||
// no lines -> balanced
|
||||
if (m_lines.size() == 0)
|
||||
return true;
|
||||
BigDecimal balance = getAcctBalance();
|
||||
boolean retValue = balance.signum() == 0;
|
||||
if (retValue)
|
||||
log.finer(toString());
|
||||
else
|
||||
log.warning("NO - Diff=" + balance + " - " + toString());
|
||||
return retValue;
|
||||
} // isAcctBalanced
|
||||
|
||||
/**
|
||||
* Return Accounting Balance
|
||||
* @return true if accounting lines are balanced
|
||||
*/
|
||||
protected BigDecimal getAcctBalance()
|
||||
{
|
||||
BigDecimal result = Env.ZERO;
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine line = (FactLine)m_lines.get(i);
|
||||
result = result.add(line.getAcctBalance());
|
||||
}
|
||||
// log.fine(result.toString());
|
||||
return result;
|
||||
} // getAcctBalance
|
||||
|
||||
/**
|
||||
* Balance Accounting Currency.
|
||||
* If the accounting currency is not balanced,
|
||||
* if Currency balancing is enabled
|
||||
* create a new line using the currency balancing account with zero source balance
|
||||
* or
|
||||
* adjust the line with the largest balance sheet account
|
||||
* or if no balance sheet account exist, the line with the largest amount
|
||||
* @return FactLine
|
||||
*/
|
||||
public FactLine balanceAccounting()
|
||||
{
|
||||
BigDecimal diff = getAcctBalance(); // DR-CR
|
||||
log.fine("Balance=" + diff
|
||||
+ ", CurrBal=" + m_acctSchema.isCurrencyBalancing()
|
||||
+ " - " + toString());
|
||||
FactLine line = null;
|
||||
|
||||
BigDecimal BSamount = Env.ZERO;
|
||||
FactLine BSline = null;
|
||||
BigDecimal PLamount = Env.ZERO;
|
||||
FactLine PLline = null;
|
||||
|
||||
// Find line biggest BalanceSheet or P&L line
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine l = (FactLine)m_lines.get(i);
|
||||
BigDecimal amt = l.getAcctBalance().abs();
|
||||
if (l.isBalanceSheet() && amt.compareTo(BSamount) > 0)
|
||||
{
|
||||
BSamount = amt;
|
||||
BSline = l;
|
||||
}
|
||||
else if (!l.isBalanceSheet() && amt.compareTo(PLamount) > 0)
|
||||
{
|
||||
PLamount = amt;
|
||||
PLline = l;
|
||||
}
|
||||
}
|
||||
|
||||
// Create Currency Balancing Entry
|
||||
if (m_acctSchema.isCurrencyBalancing())
|
||||
{
|
||||
line = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
|
||||
m_doc.get_ID(), 0, m_trxName);
|
||||
line.setDocumentInfo (m_doc, null);
|
||||
line.setPostingType (m_postingType);
|
||||
line.setAccount (m_acctSchema, m_acctSchema.getCurrencyBalancing_Acct());
|
||||
|
||||
// Amount
|
||||
line.setAmtSource(m_doc.getC_Currency_ID(), Env.ZERO, Env.ZERO);
|
||||
line.convert();
|
||||
// Accounted
|
||||
BigDecimal drAmt = Env.ZERO;
|
||||
BigDecimal crAmt = Env.ZERO;
|
||||
boolean isDR = diff.signum() < 0;
|
||||
BigDecimal difference = diff.abs();
|
||||
if (isDR)
|
||||
drAmt = difference;
|
||||
else
|
||||
crAmt = difference;
|
||||
// Switch sides
|
||||
boolean switchIt = BSline != null
|
||||
&& ((BSline.isDrSourceBalance() && isDR)
|
||||
|| (!BSline.isDrSourceBalance() && !isDR));
|
||||
if (switchIt)
|
||||
{
|
||||
drAmt = Env.ZERO;
|
||||
crAmt = Env.ZERO;
|
||||
if (isDR)
|
||||
crAmt = difference.negate();
|
||||
else
|
||||
drAmt = difference.negate();
|
||||
}
|
||||
line.setAmtAcct(drAmt, crAmt);
|
||||
log.fine(line.toString());
|
||||
m_lines.add(line);
|
||||
}
|
||||
else // Adjust biggest (Balance Sheet) line amount
|
||||
{
|
||||
if (BSline != null)
|
||||
line = BSline;
|
||||
else
|
||||
line = PLline;
|
||||
if (line == null)
|
||||
log.severe ("No Line found");
|
||||
else
|
||||
{
|
||||
log.fine("Adjusting Amt=" + diff + "; Line=" + line);
|
||||
line.currencyCorrect(diff);
|
||||
log.fine(line.toString());
|
||||
}
|
||||
} // correct biggest amount
|
||||
|
||||
return line;
|
||||
} // balanceAccounting
|
||||
|
||||
/**
|
||||
* Check Accounts of Fact Lines
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean checkAccounts()
|
||||
{
|
||||
// no lines -> nothing to distribute
|
||||
if (m_lines.size() == 0)
|
||||
return true;
|
||||
|
||||
// For all fact lines
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine line = (FactLine)m_lines.get(i);
|
||||
MAccount account = line.getAccount();
|
||||
if (account == null)
|
||||
{
|
||||
log.warning("No Account for " + line);
|
||||
return false;
|
||||
}
|
||||
MElementValue ev = account.getAccount();
|
||||
if (ev == null)
|
||||
{
|
||||
log.warning("No Element Value for " + account
|
||||
+ ": " + line);
|
||||
return false;
|
||||
}
|
||||
if (ev.isSummary())
|
||||
{
|
||||
log.warning("Cannot post to Summary Account " + ev
|
||||
+ ": " + line);
|
||||
return false;
|
||||
}
|
||||
if (!ev.isActive())
|
||||
{
|
||||
log.warning("Cannot post to Inactive Account " + ev
|
||||
+ ": " + line);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // for all lines
|
||||
|
||||
return true;
|
||||
} // checkAccounts
|
||||
|
||||
/**
|
||||
* GL Distribution of Fact Lines
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean distribute()
|
||||
{
|
||||
// no lines -> nothing to distribute
|
||||
if (m_lines.size() == 0)
|
||||
return true;
|
||||
|
||||
ArrayList<FactLine> newLines = new ArrayList<FactLine>();
|
||||
// For all fact lines
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine dLine = (FactLine)m_lines.get(i);
|
||||
MDistribution[] distributions = MDistribution.get (dLine.getAccount(),
|
||||
m_postingType, m_doc.getC_DocType_ID());
|
||||
// No Distribution for this line
|
||||
if (distributions == null || distributions.length == 0)
|
||||
continue;
|
||||
// Just the first
|
||||
if (distributions.length > 1)
|
||||
log.warning("More then one Distributiion for " + dLine.getAccount());
|
||||
MDistribution distribution = distributions[0];
|
||||
// Add Reversal
|
||||
FactLine reversal = dLine.reverse(distribution.getName());
|
||||
log.info("Reversal=" + reversal);
|
||||
newLines.add(reversal); // saved in postCommit
|
||||
// Prepare
|
||||
distribution.distribute(dLine.getAccount(), dLine.getSourceBalance(), dLine.getC_Currency_ID());
|
||||
MDistributionLine[] lines = distribution.getLines(false);
|
||||
for (int j = 0; j < lines.length; j++)
|
||||
{
|
||||
MDistributionLine dl = lines[j];
|
||||
if (!dl.isActive() || dl.getAmt().signum() == 0)
|
||||
continue;
|
||||
FactLine factLine = new FactLine (m_doc.getCtx(), m_doc.get_Table_ID(),
|
||||
m_doc.get_ID(), 0, m_trxName);
|
||||
// Set Info & Account
|
||||
factLine.setDocumentInfo(m_doc, dLine.getDocLine());
|
||||
factLine.setAccount(m_acctSchema, dl.getAccount());
|
||||
factLine.setPostingType(m_postingType);
|
||||
if (dl.isOverwriteOrg()) // set Org explicitly
|
||||
factLine.setAD_Org_ID(dl.getOrg_ID());
|
||||
//
|
||||
if (dl.getAmt().signum() < 0)
|
||||
factLine.setAmtSource(dLine.getC_Currency_ID(), null, dl.getAmt().abs());
|
||||
else
|
||||
factLine.setAmtSource(dLine.getC_Currency_ID(), dl.getAmt(), null);
|
||||
// Convert
|
||||
factLine.convert();
|
||||
//
|
||||
String description = distribution.getName() + " #" + dl.getLine();
|
||||
if (dl.getDescription() != null)
|
||||
description += " - " + dl.getDescription();
|
||||
factLine.addDescription(description);
|
||||
//
|
||||
log.info(factLine.toString());
|
||||
newLines.add(factLine);
|
||||
}
|
||||
} // for all lines
|
||||
|
||||
// Add Lines
|
||||
for (int i = 0; i < newLines.size(); i++)
|
||||
m_lines.add(newLines.get(i));
|
||||
|
||||
return true;
|
||||
} // distribute
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* String representation
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("Fact[");
|
||||
sb.append(m_doc.toString());
|
||||
sb.append(",").append(m_acctSchema.toString());
|
||||
sb.append(",PostType=").append(m_postingType);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
} // toString
|
||||
|
||||
/**
|
||||
* Get Lines
|
||||
* @return FactLine Array
|
||||
*/
|
||||
public FactLine[] getLines()
|
||||
{
|
||||
FactLine[] temp = new FactLine[m_lines.size()];
|
||||
m_lines.toArray(temp);
|
||||
return temp;
|
||||
} // getLines
|
||||
|
||||
/**
|
||||
* Save Fact
|
||||
* @param trxName transaction
|
||||
* @return true if all lines were saved
|
||||
*/
|
||||
public boolean save (String trxName)
|
||||
{
|
||||
// save Lines
|
||||
for (int i = 0; i < m_lines.size(); i++)
|
||||
{
|
||||
FactLine fl = (FactLine)m_lines.get(i);
|
||||
// log.fine("save - " + fl);
|
||||
if (!fl.save(trxName)) // abort on first error
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // commit
|
||||
|
||||
/**
|
||||
* Get Transaction
|
||||
* @return trx
|
||||
*/
|
||||
public String get_TrxName()
|
||||
{
|
||||
return m_trxName;
|
||||
} // getTrxName
|
||||
|
||||
/**
|
||||
* Set Transaction name
|
||||
* @param trxName
|
||||
*/
|
||||
private void set_TrxName(String trxName)
|
||||
{
|
||||
m_trxName = trxName;
|
||||
} // set_TrxName
|
||||
|
||||
/**
|
||||
* Fact Balance Utility
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Fact.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Balance
|
||||
{
|
||||
/**
|
||||
* New Balance
|
||||
* @param dr DR
|
||||
* @param cr CR
|
||||
*/
|
||||
public Balance (BigDecimal dr, BigDecimal cr)
|
||||
{
|
||||
DR = dr;
|
||||
CR = cr;
|
||||
}
|
||||
|
||||
/** DR Amount */
|
||||
public BigDecimal DR = Env.ZERO;
|
||||
/** CR Amount */
|
||||
public BigDecimal CR = Env.ZERO;
|
||||
|
||||
/**
|
||||
* Add
|
||||
* @param dr DR
|
||||
* @param cr CR
|
||||
*/
|
||||
public void add (BigDecimal dr, BigDecimal cr)
|
||||
{
|
||||
DR = DR.add(dr);
|
||||
CR = CR.add(cr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Balance
|
||||
* @return balance
|
||||
*/
|
||||
public BigDecimal getBalance()
|
||||
{
|
||||
return DR.subtract(CR);
|
||||
} // getBalance
|
||||
|
||||
/**
|
||||
* Get Post Balance
|
||||
* @return absolute balance - negative if reversal
|
||||
*/
|
||||
public BigDecimal getPostBalance()
|
||||
{
|
||||
BigDecimal bd = getBalance().abs();
|
||||
if (isReversal())
|
||||
return bd.negate();
|
||||
return bd;
|
||||
} // getPostBalance
|
||||
|
||||
/**
|
||||
* Zero Balance
|
||||
* @return true if 0
|
||||
*/
|
||||
public boolean isZeroBalance()
|
||||
{
|
||||
return getBalance().signum() == 0;
|
||||
} // isZeroBalance
|
||||
|
||||
/**
|
||||
* Reversal
|
||||
* @return true if both DR/CR are negative or zero
|
||||
*/
|
||||
public boolean isReversal()
|
||||
{
|
||||
return DR.signum() <= 0 && CR.signum() <= 0;
|
||||
} // isReversal
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ("Balance[");
|
||||
sb.append ("DR=").append(DR)
|
||||
.append ("-CR=").append(CR)
|
||||
.append(" = ").append(getBalance())
|
||||
.append ("]");
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
} // Balance
|
||||
|
||||
} // Fact
|
|
@ -0,0 +1,949 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Accounting Fact Entry.
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: FactLine.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public final class FactLine extends X_Fact_Acct
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param ctx context
|
||||
* @param AD_Table_ID - Table of Document Source
|
||||
* @param Record_ID - Record of document
|
||||
* @param Line_ID - Optional line id
|
||||
* @param trxName transaction
|
||||
*/
|
||||
public FactLine (Properties ctx, int AD_Table_ID, int Record_ID, int Line_ID, String trxName)
|
||||
{
|
||||
super(ctx, 0, trxName);
|
||||
setAD_Client_ID(0); // do not derive
|
||||
setAD_Org_ID(0); // do not derive
|
||||
//
|
||||
setAmtAcctCr (Env.ZERO);
|
||||
setAmtAcctDr (Env.ZERO);
|
||||
setAmtSourceCr (Env.ZERO);
|
||||
setAmtSourceDr (Env.ZERO);
|
||||
// Log.trace(this,Log.l1_User, "FactLine " + AD_Table_ID + ":" + Record_ID);
|
||||
setAD_Table_ID (AD_Table_ID);
|
||||
setRecord_ID (Record_ID);
|
||||
setLine_ID (Line_ID);
|
||||
} // FactLine
|
||||
|
||||
/** Account */
|
||||
private MAccount m_acct = null;
|
||||
/** Accounting Schema */
|
||||
private MAcctSchema m_acctSchema = null;
|
||||
/** Document Header */
|
||||
private Doc m_doc = null;
|
||||
/** Document Line */
|
||||
private DocLine m_docLine = null;
|
||||
|
||||
/**
|
||||
* Create Reversal (negate DR/CR) of the line
|
||||
* @param description new description
|
||||
* @return reversal line
|
||||
*/
|
||||
public FactLine reverse (String description)
|
||||
{
|
||||
FactLine reversal = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
|
||||
reversal.setClientOrg(this); // needs to be set explicitly
|
||||
reversal.setDocumentInfo(m_doc, m_docLine);
|
||||
reversal.setAccount(m_acctSchema, m_acct);
|
||||
reversal.setPostingType(getPostingType());
|
||||
//
|
||||
reversal.setAmtSource(getC_Currency_ID(), getAmtSourceDr().negate(), getAmtSourceCr().negate());
|
||||
reversal.convert();
|
||||
reversal.setDescription(description);
|
||||
return reversal;
|
||||
} // reverse
|
||||
|
||||
/**
|
||||
* Create Accrual (flip CR/DR) of the line
|
||||
* @param description new description
|
||||
* @return accrual line
|
||||
*/
|
||||
public FactLine accrue (String description)
|
||||
{
|
||||
FactLine accrual = new FactLine (getCtx(), getAD_Table_ID(), getRecord_ID(), getLine_ID(), get_TrxName());
|
||||
accrual.setClientOrg(this); // needs to be set explicitly
|
||||
accrual.setDocumentInfo(m_doc, m_docLine);
|
||||
accrual.setAccount(m_acctSchema, m_acct);
|
||||
accrual.setPostingType(getPostingType());
|
||||
//
|
||||
accrual.setAmtSource(getC_Currency_ID(), getAmtSourceCr(), getAmtSourceDr());
|
||||
accrual.convert();
|
||||
accrual.setDescription(description);
|
||||
return accrual;
|
||||
} // reverse
|
||||
|
||||
/**
|
||||
* Set Account Info
|
||||
* @param acctSchema account schema
|
||||
* @param acct account
|
||||
*/
|
||||
public void setAccount (MAcctSchema acctSchema, MAccount acct)
|
||||
{
|
||||
m_acctSchema = acctSchema;
|
||||
setC_AcctSchema_ID (acctSchema.getC_AcctSchema_ID());
|
||||
//
|
||||
m_acct = acct;
|
||||
if (getAD_Client_ID() == 0)
|
||||
setAD_Client_ID(m_acct.getAD_Client_ID());
|
||||
setAccount_ID (m_acct.getAccount_ID());
|
||||
setC_SubAcct_ID(m_acct.getC_SubAcct_ID());
|
||||
} // setAccount
|
||||
|
||||
/**
|
||||
* Set Source Amounts
|
||||
* @param C_Currency_ID currency
|
||||
* @param AmtSourceDr source amount dr
|
||||
* @param AmtSourceCr source amount cr
|
||||
* @return true, if any if the amount is not zero
|
||||
*/
|
||||
public boolean setAmtSource (int C_Currency_ID, BigDecimal AmtSourceDr, BigDecimal AmtSourceCr)
|
||||
{
|
||||
setC_Currency_ID (C_Currency_ID);
|
||||
if (AmtSourceDr != null)
|
||||
setAmtSourceDr (AmtSourceDr);
|
||||
if (AmtSourceCr != null)
|
||||
setAmtSourceCr (AmtSourceCr);
|
||||
// one needs to be non zero
|
||||
if (getAmtSourceDr().equals(Env.ZERO) && getAmtSourceCr().equals(Env.ZERO))
|
||||
return false;
|
||||
// Currency Precision
|
||||
int precision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
|
||||
if (AmtSourceDr != null && AmtSourceDr.scale() > precision)
|
||||
{
|
||||
BigDecimal AmtSourceDr1 = AmtSourceDr.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||
log.warning("Source DR Precision " + AmtSourceDr + " -> " + AmtSourceDr1);
|
||||
setAmtSourceDr(AmtSourceDr1);
|
||||
}
|
||||
if (AmtSourceCr != null && AmtSourceCr.scale() > precision)
|
||||
{
|
||||
BigDecimal AmtSourceCr1 = AmtSourceCr.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||
log.warning("Source CR Precision " + AmtSourceCr + " -> " + AmtSourceCr1);
|
||||
setAmtSourceCr(AmtSourceCr1);
|
||||
}
|
||||
return true;
|
||||
} // setAmtSource
|
||||
|
||||
/**
|
||||
* Set Accounted Amounts (alternative: call convert)
|
||||
* @param AmtAcctDr acct amount dr
|
||||
* @param AmtAcctCr acct amount cr
|
||||
*/
|
||||
public void setAmtAcct(BigDecimal AmtAcctDr, BigDecimal AmtAcctCr)
|
||||
{
|
||||
setAmtAcctDr (AmtAcctDr);
|
||||
setAmtAcctCr (AmtAcctCr);
|
||||
} // setAmtAcct
|
||||
|
||||
/**
|
||||
* Set Document Info
|
||||
* @param doc document
|
||||
* @param docLine doc line
|
||||
*/
|
||||
public void setDocumentInfo(Doc doc, DocLine docLine)
|
||||
{
|
||||
m_doc = doc;
|
||||
m_docLine = docLine;
|
||||
// reset
|
||||
setAD_Org_ID(0);
|
||||
setC_SalesRegion_ID(0);
|
||||
// Client
|
||||
if (getAD_Client_ID() == 0)
|
||||
setAD_Client_ID (m_doc.getAD_Client_ID());
|
||||
// Date Trx
|
||||
setDateTrx (m_doc.getDateDoc());
|
||||
if (m_docLine != null && m_docLine.getDateDoc() != null)
|
||||
setDateTrx (m_docLine.getDateDoc());
|
||||
// Date Acct
|
||||
setDateAcct (m_doc.getDateAcct());
|
||||
if (m_docLine != null && m_docLine.getDateAcct() != null)
|
||||
setDateAcct (m_docLine.getDateAcct());
|
||||
// Period, Tax
|
||||
if (m_docLine != null && m_docLine.getC_Period_ID() != 0)
|
||||
setC_Period_ID(m_docLine.getC_Period_ID());
|
||||
else
|
||||
setC_Period_ID (m_doc.getC_Period_ID());
|
||||
if (m_docLine != null)
|
||||
setC_Tax_ID (m_docLine.getC_Tax_ID());
|
||||
// Description
|
||||
StringBuffer description = new StringBuffer(m_doc.getDocumentNo());
|
||||
if (m_docLine != null)
|
||||
{
|
||||
description.append(" #").append(m_docLine.getLine());
|
||||
if (m_docLine.getDescription() != null)
|
||||
description.append(" (").append(m_docLine.getDescription()).append(")");
|
||||
else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
|
||||
description.append(" (").append(m_doc.getDescription()).append(")");
|
||||
}
|
||||
else if (m_doc.getDescription() != null && m_doc.getDescription().length() > 0)
|
||||
description.append(" (").append(m_doc.getDescription()).append(")");
|
||||
setDescription(description.toString());
|
||||
// Journal Info
|
||||
setGL_Budget_ID (m_doc.getGL_Budget_ID());
|
||||
setGL_Category_ID (m_doc.getGL_Category_ID());
|
||||
|
||||
// Product
|
||||
if (m_docLine != null)
|
||||
setM_Product_ID (m_docLine.getM_Product_ID());
|
||||
if (getM_Product_ID() == 0)
|
||||
setM_Product_ID (m_doc.getM_Product_ID());
|
||||
// UOM
|
||||
if (m_docLine != null)
|
||||
setC_UOM_ID (m_docLine.getC_UOM_ID());
|
||||
// Qty
|
||||
if (get_Value("Qty") == null) // not previously set
|
||||
{
|
||||
setQty (m_doc.getQty()); // neg = outgoing
|
||||
if (m_docLine != null)
|
||||
setQty (m_docLine.getQty());
|
||||
}
|
||||
|
||||
// Loc From (maybe set earlier)
|
||||
if (getC_LocFrom_ID() == 0 && m_docLine != null)
|
||||
setC_LocFrom_ID (m_docLine.getC_LocFrom_ID());
|
||||
if (getC_LocFrom_ID() == 0)
|
||||
setC_LocFrom_ID (m_doc.getC_LocFrom_ID());
|
||||
// Loc To (maybe set earlier)
|
||||
if (getC_LocTo_ID() == 0 && m_docLine != null)
|
||||
setC_LocTo_ID (m_docLine.getC_LocTo_ID());
|
||||
if (getC_LocTo_ID() == 0)
|
||||
setC_LocTo_ID (m_doc.getC_LocTo_ID());
|
||||
// BPartner
|
||||
if (m_docLine != null)
|
||||
setC_BPartner_ID (m_docLine.getC_BPartner_ID());
|
||||
if (getC_BPartner_ID() == 0)
|
||||
setC_BPartner_ID (m_doc.getC_BPartner_ID());
|
||||
// Sales Region from BPLocation/Sales Rep
|
||||
// Trx Org
|
||||
if (m_docLine != null)
|
||||
setAD_OrgTrx_ID (m_docLine.getAD_OrgTrx_ID());
|
||||
if (getAD_OrgTrx_ID() == 0)
|
||||
setAD_OrgTrx_ID (m_doc.getAD_OrgTrx_ID());
|
||||
// Project
|
||||
if (m_docLine != null)
|
||||
setC_Project_ID (m_docLine.getC_Project_ID());
|
||||
if (getC_Project_ID() == 0)
|
||||
setC_Project_ID (m_doc.getC_Project_ID());
|
||||
// Campaign
|
||||
if (m_docLine != null)
|
||||
setC_Campaign_ID (m_docLine.getC_Campaign_ID());
|
||||
if (getC_Campaign_ID() == 0)
|
||||
setC_Campaign_ID (m_doc.getC_Campaign_ID());
|
||||
// Activity
|
||||
if (m_docLine != null)
|
||||
setC_Activity_ID (m_docLine.getC_Activity_ID());
|
||||
if (getC_Activity_ID() == 0)
|
||||
setC_Activity_ID (m_doc.getC_Activity_ID());
|
||||
// User List 1
|
||||
if (m_docLine != null)
|
||||
setUser1_ID (m_docLine.getUser1_ID());
|
||||
if (getUser1_ID() == 0)
|
||||
setUser1_ID (m_doc.getUser1_ID());
|
||||
// User List 2
|
||||
if (m_docLine != null)
|
||||
setUser2_ID (m_docLine.getUser2_ID());
|
||||
if (getUser2_ID() == 0)
|
||||
setUser2_ID (m_doc.getUser2_ID());
|
||||
// User Defined
|
||||
|
||||
} // setDocumentInfo
|
||||
|
||||
/**
|
||||
* Get Document Line
|
||||
* @return doc line
|
||||
*/
|
||||
protected DocLine getDocLine()
|
||||
{
|
||||
return m_docLine;
|
||||
} // getDocLine
|
||||
|
||||
/**
|
||||
* Set Description
|
||||
* @param description description
|
||||
*/
|
||||
public void addDescription (String description)
|
||||
{
|
||||
String original = getDescription();
|
||||
if (original == null || original.trim().length() == 0)
|
||||
super.setDescription(description);
|
||||
else
|
||||
super.setDescription(original + " - " + description);
|
||||
} // addDescription
|
||||
|
||||
/**
|
||||
* Set Warehouse Locator.
|
||||
* - will overwrite Organization -
|
||||
* @param M_Locator_ID locator
|
||||
*/
|
||||
public void setM_Locator_ID (int M_Locator_ID)
|
||||
{
|
||||
super.setM_Locator_ID (M_Locator_ID);
|
||||
setAD_Org_ID(0); // reset
|
||||
} // setM_Locator_ID
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Set Location
|
||||
* @param C_Location_ID location
|
||||
* @param isFrom from
|
||||
*/
|
||||
public void setLocation (int C_Location_ID, boolean isFrom)
|
||||
{
|
||||
if (isFrom)
|
||||
setC_LocFrom_ID (C_Location_ID);
|
||||
else
|
||||
setC_LocTo_ID (C_Location_ID);
|
||||
} // setLocator
|
||||
|
||||
/**
|
||||
* Set Location from Locator
|
||||
* @param M_Locator_ID locator
|
||||
* @param isFrom from
|
||||
*/
|
||||
public void setLocationFromLocator (int M_Locator_ID, boolean isFrom)
|
||||
{
|
||||
if (M_Locator_ID == 0)
|
||||
return;
|
||||
int C_Location_ID = 0;
|
||||
String sql = "SELECT w.C_Location_ID FROM M_Warehouse w, M_Locator l "
|
||||
+ "WHERE w.M_Warehouse_ID=l.M_Warehouse_ID AND l.M_Locator_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, M_Locator_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
C_Location_ID = rs.getInt(1);
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
return;
|
||||
}
|
||||
if (C_Location_ID != 0)
|
||||
setLocation (C_Location_ID, isFrom);
|
||||
} // setLocationFromLocator
|
||||
|
||||
/**
|
||||
* Set Location from Busoness Partner Location
|
||||
* @param C_BPartner_Location_ID bp location
|
||||
* @param isFrom from
|
||||
*/
|
||||
public void setLocationFromBPartner (int C_BPartner_Location_ID, boolean isFrom)
|
||||
{
|
||||
if (C_BPartner_Location_ID == 0)
|
||||
return;
|
||||
int C_Location_ID = 0;
|
||||
String sql = "SELECT C_Location_ID FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, C_BPartner_Location_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
C_Location_ID = rs.getInt(1);
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
return;
|
||||
}
|
||||
if (C_Location_ID != 0)
|
||||
setLocation (C_Location_ID, isFrom);
|
||||
} // setLocationFromBPartner
|
||||
|
||||
/**
|
||||
* Set Location from Organization
|
||||
* @param AD_Org_ID org
|
||||
* @param isFrom from
|
||||
*/
|
||||
public void setLocationFromOrg (int AD_Org_ID, boolean isFrom)
|
||||
{
|
||||
if (AD_Org_ID == 0)
|
||||
return;
|
||||
int C_Location_ID = 0;
|
||||
String sql = "SELECT C_Location_ID FROM AD_OrgInfo WHERE AD_Org_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, AD_Org_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
C_Location_ID = rs.getInt(1);
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
return;
|
||||
}
|
||||
if (C_Location_ID != 0)
|
||||
setLocation (C_Location_ID, isFrom);
|
||||
} // setLocationFromOrg
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Returns Source Balance of line
|
||||
* @return source balance
|
||||
*/
|
||||
public BigDecimal getSourceBalance()
|
||||
{
|
||||
if (getAmtSourceDr() == null)
|
||||
setAmtSourceDr (Env.ZERO);
|
||||
if (getAmtSourceCr() == null)
|
||||
setAmtSourceCr (Env.ZERO);
|
||||
//
|
||||
return getAmtSourceDr().subtract(getAmtSourceCr());
|
||||
} // getSourceBalance
|
||||
|
||||
/**
|
||||
* Is Debit Source Balance
|
||||
* @return true if DR source balance
|
||||
*/
|
||||
public boolean isDrSourceBalance()
|
||||
{
|
||||
return getSourceBalance().signum() != -1;
|
||||
} // isDrSourceBalance
|
||||
|
||||
/**
|
||||
* Get Accounted Balance
|
||||
* @return accounting balance
|
||||
*/
|
||||
public BigDecimal getAcctBalance()
|
||||
{
|
||||
if (getAmtAcctDr() == null)
|
||||
setAmtAcctDr (Env.ZERO);
|
||||
if (getAmtAcctCr() == null)
|
||||
setAmtAcctCr (Env.ZERO);
|
||||
return getAmtAcctDr().subtract(getAmtAcctCr());
|
||||
} // getAcctBalance
|
||||
|
||||
/**
|
||||
* Is Account on Balance Sheet
|
||||
* @return true if account is a balance sheet account
|
||||
*/
|
||||
public boolean isBalanceSheet()
|
||||
{
|
||||
return m_acct.isBalanceSheet();
|
||||
} // isBalanceSheet
|
||||
|
||||
/**
|
||||
* Currect Accounting Amount.
|
||||
* <pre>
|
||||
* Example: 1 -1 1 -1
|
||||
* Old 100/0 100/0 0/100 0/100
|
||||
* New 99/0 101/0 0/99 0/101
|
||||
* </pre>
|
||||
* @param deltaAmount delta amount
|
||||
*/
|
||||
public void currencyCorrect (BigDecimal deltaAmount)
|
||||
{
|
||||
boolean negative = deltaAmount.compareTo(Env.ZERO) < 0;
|
||||
boolean adjustDr = getAmtAcctDr().abs().compareTo(getAmtAcctCr().abs()) > 0;
|
||||
|
||||
log.fine(deltaAmount.toString()
|
||||
+ "; Old-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr()
|
||||
+ "; Negative=" + negative + "; AdjustDr=" + adjustDr);
|
||||
|
||||
if (adjustDr)
|
||||
if (negative)
|
||||
setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
|
||||
else
|
||||
setAmtAcctDr (getAmtAcctDr().subtract(deltaAmount));
|
||||
else
|
||||
if (negative)
|
||||
setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
|
||||
else
|
||||
setAmtAcctCr (getAmtAcctCr().add(deltaAmount));
|
||||
|
||||
log.fine("New-AcctDr=" + getAmtAcctDr() + ",AcctCr=" + getAmtAcctCr());
|
||||
} // currencyCorrect
|
||||
|
||||
/**
|
||||
* Convert to Accounted Currency
|
||||
* @return true if converted
|
||||
*/
|
||||
public boolean convert ()
|
||||
{
|
||||
// Document has no currency
|
||||
if (getC_Currency_ID() == Doc.NO_CURRENCY)
|
||||
setC_Currency_ID (m_acctSchema.getC_Currency_ID());
|
||||
|
||||
if (m_acctSchema.getC_Currency_ID() == getC_Currency_ID())
|
||||
{
|
||||
setAmtAcctDr (getAmtSourceDr());
|
||||
setAmtAcctCr (getAmtSourceCr());
|
||||
return true;
|
||||
}
|
||||
// Get Conversion Type from Line or Header
|
||||
int C_ConversionType_ID = 0;
|
||||
int AD_Org_ID = 0;
|
||||
if (m_docLine != null) // get from line
|
||||
{
|
||||
C_ConversionType_ID = m_docLine.getC_ConversionType_ID();
|
||||
AD_Org_ID = m_docLine.getAD_Org_ID();
|
||||
}
|
||||
if (C_ConversionType_ID == 0) // get from header
|
||||
{
|
||||
if (m_doc == null)
|
||||
{
|
||||
log.severe ("No Document VO");
|
||||
return false;
|
||||
}
|
||||
C_ConversionType_ID = m_doc.getC_ConversionType_ID();
|
||||
if (AD_Org_ID == 0)
|
||||
AD_Org_ID = m_doc.getAD_Org_ID();
|
||||
}
|
||||
setAmtAcctDr (MConversionRate.convert (getCtx(),
|
||||
getAmtSourceDr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
|
||||
getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
|
||||
if (getAmtAcctDr() == null)
|
||||
return false;
|
||||
setAmtAcctCr (MConversionRate.convert (getCtx(),
|
||||
getAmtSourceCr(), getC_Currency_ID(), m_acctSchema.getC_Currency_ID(),
|
||||
getDateAcct(), C_ConversionType_ID, m_doc.getAD_Client_ID(), AD_Org_ID));
|
||||
return true;
|
||||
} // convert
|
||||
|
||||
/**
|
||||
* Get Account
|
||||
* @return account
|
||||
*/
|
||||
public MAccount getAccount()
|
||||
{
|
||||
return m_acct;
|
||||
} // getAccount
|
||||
|
||||
/**
|
||||
* To String
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer("FactLine=[");
|
||||
sb.append(getAD_Table_ID()).append(":").append(getRecord_ID())
|
||||
.append(",").append(m_acct)
|
||||
.append(",Cur=").append(getC_Currency_ID())
|
||||
.append(", DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
|
||||
.append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
} // toString
|
||||
|
||||
|
||||
/**
|
||||
* Get AD_Org_ID (balancing segment).
|
||||
* (if not set directly - from document line, document, account, locator)
|
||||
* <p>
|
||||
* Note that Locator needs to be set before - otherwise
|
||||
* segment balancing might produce the wrong results
|
||||
* @return AD_Org_ID
|
||||
*/
|
||||
public int getAD_Org_ID()
|
||||
{
|
||||
if (super.getAD_Org_ID() != 0) // set earlier
|
||||
return super.getAD_Org_ID();
|
||||
// Prio 1 - get from locator - if exist
|
||||
if (getM_Locator_ID() != 0)
|
||||
{
|
||||
String sql = "SELECT AD_Org_ID FROM M_Locator WHERE M_Locator_ID=? AND AD_Client_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, getM_Locator_ID());
|
||||
pstmt.setInt(2, getAD_Client_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
setAD_Org_ID (rs.getInt(1));
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (1 from M_Locator_ID=" + getM_Locator_ID() + ")");
|
||||
}
|
||||
else
|
||||
log.log(Level.SEVERE, "AD_Org_ID - Did not find M_Locator_ID=" + getM_Locator_ID());
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
} // M_Locator_ID != 0
|
||||
|
||||
// Prio 2 - get from doc line - if exists (document context overwrites)
|
||||
if (m_docLine != null && super.getAD_Org_ID() == 0)
|
||||
{
|
||||
setAD_Org_ID (m_docLine.getAD_Org_ID());
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (2 from DocumentLine)");
|
||||
}
|
||||
// Prio 3 - get from doc - if not GL
|
||||
if (m_doc != null && super.getAD_Org_ID() == 0)
|
||||
{
|
||||
if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
|
||||
{
|
||||
setAD_Org_ID (m_acct.getAD_Org_ID()); // inter-company GL
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Acct)");
|
||||
}
|
||||
else
|
||||
{
|
||||
setAD_Org_ID (m_doc.getAD_Org_ID());
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (3 from Document)");
|
||||
}
|
||||
}
|
||||
// Prio 4 - get from account - if not GL
|
||||
if (m_doc != null && super.getAD_Org_ID() == 0)
|
||||
{
|
||||
if (Doc.DOCTYPE_GLJournal.equals (m_doc.getDocumentType()))
|
||||
{
|
||||
setAD_Org_ID (m_doc.getAD_Org_ID());
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Document)");
|
||||
}
|
||||
else
|
||||
{
|
||||
setAD_Org_ID (m_acct.getAD_Org_ID());
|
||||
log.finer("AD_Org_ID=" + super.getAD_Org_ID() + " (4 from Acct)");
|
||||
}
|
||||
}
|
||||
return super.getAD_Org_ID();
|
||||
} // setAD_Org_ID
|
||||
|
||||
|
||||
/**
|
||||
* Get/derive Sales Region
|
||||
* @return Sales Region
|
||||
*/
|
||||
public int getC_SalesRegion_ID ()
|
||||
{
|
||||
if (super.getC_SalesRegion_ID() != 0)
|
||||
return super.getC_SalesRegion_ID();
|
||||
//
|
||||
if (m_docLine != null)
|
||||
setC_SalesRegion_ID (m_docLine.getC_SalesRegion_ID());
|
||||
if (m_doc != null)
|
||||
{
|
||||
if (super.getC_SalesRegion_ID() == 0)
|
||||
setC_SalesRegion_ID (m_doc.getC_SalesRegion_ID());
|
||||
if (super.getC_SalesRegion_ID() == 0 && m_doc.getBP_C_SalesRegion_ID() > 0)
|
||||
setC_SalesRegion_ID (m_doc.getBP_C_SalesRegion_ID());
|
||||
// derive SalesRegion if AcctSegment
|
||||
if (super.getC_SalesRegion_ID() == 0
|
||||
&& m_doc.getC_BPartner_Location_ID() != 0
|
||||
&& m_doc.getBP_C_SalesRegion_ID() == -1) // never tried
|
||||
// && m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion))
|
||||
{
|
||||
String sql = "SELECT COALESCE(C_SalesRegion_ID,0) FROM C_BPartner_Location WHERE C_BPartner_Location_ID=?";
|
||||
setC_SalesRegion_ID (DB.getSQLValue(null,
|
||||
sql, m_doc.getC_BPartner_Location_ID()));
|
||||
if (super.getC_SalesRegion_ID() != 0) // save in VO
|
||||
{
|
||||
m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
|
||||
log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from BPL)" );
|
||||
}
|
||||
else // From Sales Rep of Document -> Sales Region
|
||||
{
|
||||
sql = "SELECT COALESCE(MAX(C_SalesRegion_ID),0) FROM C_SalesRegion WHERE SalesRep_ID=?";
|
||||
setC_SalesRegion_ID (DB.getSQLValue(null,
|
||||
sql, m_doc.getSalesRep_ID()));
|
||||
if (super.getC_SalesRegion_ID() != 0) // save in VO
|
||||
{
|
||||
m_doc.setBP_C_SalesRegion_ID(super.getC_SalesRegion_ID());
|
||||
log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID() + " (from SR)" );
|
||||
}
|
||||
else
|
||||
m_doc.setBP_C_SalesRegion_ID(-2); // don't try again
|
||||
}
|
||||
}
|
||||
if (m_acct != null && super.getC_SalesRegion_ID() == 0)
|
||||
setC_SalesRegion_ID (m_acct.getC_SalesRegion_ID());
|
||||
}
|
||||
//
|
||||
// log.fine("C_SalesRegion_ID=" + super.getC_SalesRegion_ID()
|
||||
// + ", C_BPartner_Location_ID=" + m_docVO.C_BPartner_Location_ID
|
||||
// + ", BP_C_SalesRegion_ID=" + m_docVO.BP_C_SalesRegion_ID
|
||||
// + ", SR=" + m_acctSchema.isAcctSchemaElement(MAcctSchemaElement.ELEMENTTYPE_SalesRegion));
|
||||
return super.getC_SalesRegion_ID();
|
||||
} // getC_SalesRegion_ID
|
||||
|
||||
|
||||
/**
|
||||
* Before Save
|
||||
* @param newRecord new
|
||||
* @return true
|
||||
*/
|
||||
protected boolean beforeSave (boolean newRecord)
|
||||
{
|
||||
if (newRecord)
|
||||
{
|
||||
log.fine(toString());
|
||||
//
|
||||
getAD_Org_ID();
|
||||
getC_SalesRegion_ID();
|
||||
// Set Default Account Info
|
||||
if (getM_Product_ID() == 0)
|
||||
setM_Product_ID (m_acct.getM_Product_ID());
|
||||
if (getC_LocFrom_ID() == 0)
|
||||
setC_LocFrom_ID (m_acct.getC_LocFrom_ID());
|
||||
if (getC_LocTo_ID() == 0)
|
||||
setC_LocTo_ID (m_acct.getC_LocTo_ID());
|
||||
if (getC_BPartner_ID() == 0)
|
||||
setC_BPartner_ID (m_acct.getC_BPartner_ID());
|
||||
if (getAD_OrgTrx_ID() == 0)
|
||||
setAD_OrgTrx_ID (m_acct.getAD_OrgTrx_ID());
|
||||
if (getC_Project_ID() == 0)
|
||||
setC_Project_ID (m_acct.getC_Project_ID());
|
||||
if (getC_Campaign_ID() == 0)
|
||||
setC_Campaign_ID (m_acct.getC_Campaign_ID());
|
||||
if (getC_Activity_ID() == 0)
|
||||
setC_Activity_ID (m_acct.getC_Activity_ID());
|
||||
if (getUser1_ID() == 0)
|
||||
setUser1_ID (m_acct.getUser1_ID());
|
||||
if (getUser2_ID() == 0)
|
||||
setUser2_ID (m_acct.getUser2_ID());
|
||||
|
||||
// Revenue Recognition for AR Invoices
|
||||
if (m_doc.getDocumentType().equals(Doc.DOCTYPE_ARInvoice)
|
||||
&& m_docLine != null
|
||||
&& m_docLine.getC_RevenueRecognition_ID() != 0)
|
||||
{
|
||||
int AD_User_ID = 0;
|
||||
setAccount_ID (
|
||||
createRevenueRecognition (
|
||||
m_docLine.getC_RevenueRecognition_ID(), m_docLine.get_ID(),
|
||||
getAD_Client_ID(), getAD_Org_ID(), AD_User_ID,
|
||||
getAccount_ID(), getC_SubAcct_ID(),
|
||||
getM_Product_ID(), getC_BPartner_ID(), getAD_OrgTrx_ID(),
|
||||
getC_LocFrom_ID(), getC_LocTo_ID(),
|
||||
getC_SalesRegion_ID(), getC_Project_ID(),
|
||||
getC_Campaign_ID(), getC_Activity_ID(),
|
||||
getUser1_ID(), getUser2_ID(),
|
||||
getUserElement1_ID(), getUserElement2_ID())
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // beforeSave
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Revenue Recognition.
|
||||
* Called from FactLine.save
|
||||
* <p>
|
||||
* Create Revenue recognition plan and return Unearned Revenue account
|
||||
* to be used instead of Revenue Account. If not found, it returns
|
||||
* the revenue account.
|
||||
*
|
||||
* @param C_RevenueRecognition_ID revenue recognition
|
||||
* @param C_InvoiceLine_ID invoice line
|
||||
* @param AD_Client_ID client
|
||||
* @param AD_Org_ID org
|
||||
* @param AD_User_ID user
|
||||
* @param Account_ID of Revenue Account
|
||||
* @param C_SubAcct_ID sub account
|
||||
* @param M_Product_ID product
|
||||
* @param C_BPartner_ID bpartner
|
||||
* @param AD_OrgTrx_ID trx org
|
||||
* @param C_LocFrom_ID loc from
|
||||
* @param C_LocTo_ID loc to
|
||||
* @param C_SRegion_ID sales region
|
||||
* @param C_Project_ID project
|
||||
* @param C_Campaign_ID campaign
|
||||
* @param C_Activity_ID activity
|
||||
* @param User1_ID user1
|
||||
* @param User2_ID user2
|
||||
* @param UserElement1_ID user element 1
|
||||
* @param UserElement2_ID user element 2
|
||||
* @return Account_ID for Unearned Revenue or Revenue Account if not found
|
||||
*/
|
||||
private int createRevenueRecognition (
|
||||
int C_RevenueRecognition_ID, int C_InvoiceLine_ID,
|
||||
int AD_Client_ID, int AD_Org_ID, int AD_User_ID,
|
||||
int Account_ID, int C_SubAcct_ID,
|
||||
int M_Product_ID, int C_BPartner_ID, int AD_OrgTrx_ID,
|
||||
int C_LocFrom_ID, int C_LocTo_ID, int C_SRegion_ID, int C_Project_ID,
|
||||
int C_Campaign_ID, int C_Activity_ID,
|
||||
int User1_ID, int User2_ID, int UserElement1_ID, int UserElement2_ID)
|
||||
{
|
||||
log.fine("From Accout_ID=" + Account_ID);
|
||||
// get VC for P_Revenue (from Product)
|
||||
MAccount revenue = MAccount.get(getCtx(),
|
||||
AD_Client_ID, AD_Org_ID, getC_AcctSchema_ID(), Account_ID, C_SubAcct_ID,
|
||||
M_Product_ID, C_BPartner_ID, AD_OrgTrx_ID, C_LocFrom_ID, C_LocTo_ID, C_SRegion_ID,
|
||||
C_Project_ID, C_Campaign_ID, C_Activity_ID,
|
||||
User1_ID, User2_ID, UserElement1_ID, UserElement2_ID);
|
||||
if (revenue != null && revenue.get_ID() == 0)
|
||||
revenue.save();
|
||||
if (revenue == null || revenue.get_ID() == 0)
|
||||
{
|
||||
log.severe ("Revenue_Acct not found");
|
||||
return Account_ID;
|
||||
}
|
||||
int P_Revenue_Acct = revenue.get_ID();
|
||||
|
||||
// get Unearned Revenue Acct from BPartner Group
|
||||
int UnearnedRevenue_Acct = 0;
|
||||
int new_Account_ID = 0;
|
||||
String sql = "SELECT ga.UnearnedRevenue_Acct, vc.Account_ID "
|
||||
+ "FROM C_BP_Group_Acct ga, C_BPartner p, C_ValidCombination vc "
|
||||
+ "WHERE ga.C_BP_Group_ID=p.C_BP_Group_ID"
|
||||
+ " AND ga.UnearnedRevenue_Acct=vc.C_ValidCombination_ID"
|
||||
+ " AND ga.C_AcctSchema_ID=? AND p.C_BPartner_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, getC_AcctSchema_ID());
|
||||
pstmt.setInt(2, C_BPartner_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
UnearnedRevenue_Acct = rs.getInt(1);
|
||||
new_Account_ID = rs.getInt(2);
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
if (new_Account_ID == 0)
|
||||
{
|
||||
log.severe ("UnearnedRevenue_Acct not found");
|
||||
return Account_ID;
|
||||
}
|
||||
|
||||
MRevenueRecognitionPlan plan = new MRevenueRecognitionPlan(getCtx(), 0, null);
|
||||
plan.setC_RevenueRecognition_ID (C_RevenueRecognition_ID);
|
||||
plan.setC_AcctSchema_ID (getC_AcctSchema_ID());
|
||||
plan.setC_InvoiceLine_ID (C_InvoiceLine_ID);
|
||||
plan.setUnEarnedRevenue_Acct (UnearnedRevenue_Acct);
|
||||
plan.setP_Revenue_Acct (P_Revenue_Acct);
|
||||
plan.setC_Currency_ID (getC_Currency_ID());
|
||||
plan.setTotalAmt (getAcctBalance());
|
||||
if (!plan.save(get_TrxName()))
|
||||
{
|
||||
log.severe ("Plan NOT created");
|
||||
return Account_ID;
|
||||
}
|
||||
log.fine("From Acctount_ID=" + Account_ID + " to " + new_Account_ID
|
||||
+ " - Plan from UnearnedRevenue_Acct=" + UnearnedRevenue_Acct + " to Revenue_Acct=" + P_Revenue_Acct);
|
||||
return new_Account_ID;
|
||||
} // createRevenueRecognition
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Update Line with reversed Original Amount in Accounting Currency.
|
||||
* Also copies original dimensions like Project, etc.
|
||||
* Called from Doc_MatchInv
|
||||
* @param AD_Table_ID table
|
||||
* @param Record_ID record
|
||||
* @param Line_ID line
|
||||
* @param multiplier targetQty/documentQty
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean updateReverseLine (int AD_Table_ID, int Record_ID, int Line_ID,
|
||||
BigDecimal multiplier)
|
||||
{
|
||||
boolean success = false;
|
||||
|
||||
String sql = "SELECT * "
|
||||
+ "FROM Fact_Acct "
|
||||
+ "WHERE C_AcctSchema_ID=? AND AD_Table_ID=? AND Record_ID=?"
|
||||
+ " AND Line_ID=? AND Account_ID=?";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||
pstmt.setInt(1, getC_AcctSchema_ID());
|
||||
pstmt.setInt(2, AD_Table_ID);
|
||||
pstmt.setInt(3, Record_ID);
|
||||
pstmt.setInt(4, Line_ID);
|
||||
pstmt.setInt(5, m_acct.getAccount_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
MFactAcct fact = new MFactAcct(getCtx(), rs, get_TrxName());
|
||||
// Accounted Amounts - reverse
|
||||
BigDecimal dr = fact.getAmtAcctDr();
|
||||
BigDecimal cr = fact.getAmtAcctCr();
|
||||
setAmtAcctDr (cr.multiply(multiplier));
|
||||
setAmtAcctCr (dr.multiply(multiplier));
|
||||
// Source Amounts
|
||||
setAmtSourceDr (getAmtAcctDr());
|
||||
setAmtSourceCr (getAmtAcctCr());
|
||||
//
|
||||
success = true;
|
||||
log.fine(new StringBuffer("(Table=").append(AD_Table_ID)
|
||||
.append(",Record_ID=").append(Record_ID)
|
||||
.append(",Line=").append(Record_ID)
|
||||
.append(", Account=").append(m_acct)
|
||||
.append(",dr=").append(dr).append(",cr=").append(cr)
|
||||
.append(") - DR=").append(getAmtSourceDr()).append("|").append(getAmtAcctDr())
|
||||
.append(", CR=").append(getAmtSourceCr()).append("|").append(getAmtAcctCr())
|
||||
.toString());
|
||||
// Dimensions
|
||||
setAD_OrgTrx_ID(fact.getAD_OrgTrx_ID());
|
||||
setC_Project_ID (fact.getC_Project_ID());
|
||||
setC_Activity_ID(fact.getC_Activity_ID());
|
||||
setC_Campaign_ID(fact.getC_Campaign_ID());
|
||||
setC_SalesRegion_ID(fact.getC_SalesRegion_ID());
|
||||
setC_LocFrom_ID(fact.getC_LocFrom_ID());
|
||||
setC_LocTo_ID(fact.getC_LocTo_ID());
|
||||
setM_Product_ID(fact.getM_Product_ID());
|
||||
setM_Locator_ID(fact.getM_Locator_ID());
|
||||
setUser1_ID(fact.getUser1_ID());
|
||||
setUser2_ID(fact.getUser2_ID());
|
||||
setC_UOM_ID(fact.getC_UOM_ID());
|
||||
setC_Tax_ID(fact.getC_Tax_ID());
|
||||
// Org for cross charge
|
||||
setAD_Org_ID (fact.getAD_Org_ID());
|
||||
}
|
||||
else
|
||||
log.warning(new StringBuffer("Not Found (try later) ")
|
||||
.append(",C_AcctSchema_ID=").append(getC_AcctSchema_ID())
|
||||
.append(", AD_Table_ID=").append(AD_Table_ID)
|
||||
.append(",Record_ID=").append(Record_ID)
|
||||
.append(",Line_ID=").append(Line_ID)
|
||||
.append(", Account_ID=").append(m_acct.getAccount_ID()).toString());
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
return success;
|
||||
} // updateReverseLine
|
||||
|
||||
} // FactLine
|
|
@ -0,0 +1,165 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Automatic Matching.
|
||||
* Inv
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Matcher.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Matcher
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param AD_Client_ID Client
|
||||
* @param trxName transaction
|
||||
*/
|
||||
public Matcher (int AD_Client_ID, String trxName)
|
||||
{
|
||||
m_AD_Client_ID = AD_Client_ID;
|
||||
m_trxName = trxName;
|
||||
} // Matcher
|
||||
|
||||
/** Client */
|
||||
private int m_AD_Client_ID;
|
||||
/** Transaction */
|
||||
private String m_trxName = null;
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger (getClass());
|
||||
|
||||
/**
|
||||
* Matching
|
||||
* <pre>
|
||||
* Derive Invoice-Receipt Match from PO-Invoice and PO-Receipt
|
||||
* Purchase Order (20)
|
||||
* - Invoice1 (10)
|
||||
* - Invoice2 (10)
|
||||
* - Receipt1 (5)
|
||||
* - Receipt2 (15)
|
||||
*
|
||||
* (a) Creates Directs
|
||||
* - Invoice1 - Receipt1 (5)
|
||||
* - Invoice2 - Receipt2 (10)
|
||||
*
|
||||
* (b) Creates Indirects
|
||||
* - Invoice1 - Receipt2 (5)
|
||||
* (Not imlemented)
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* @return number of records created
|
||||
*/
|
||||
public int match()
|
||||
{
|
||||
int counter = 0;
|
||||
// (a) Direct Matches
|
||||
String sql = "SELECT m1.AD_Client_ID,m2.AD_Org_ID, " // 1..2
|
||||
+ "m1.C_InvoiceLine_ID,m2.M_InOutLine_ID,m1.M_Product_ID, " // 3..5
|
||||
+ "m1.DateTrx,m2.DateTrx, m1.Qty, m2.Qty " // 6..9
|
||||
+ "FROM M_MatchPO m1, M_MatchPO m2 "
|
||||
+ "WHERE m1.C_OrderLine_ID=m2.C_OrderLine_ID"
|
||||
+ " AND m1.M_InOutLine_ID IS NULL"
|
||||
+ " AND m2.C_InvoiceLine_ID IS NULL"
|
||||
+ " AND m1.M_Product_ID=m2.M_Product_ID"
|
||||
+ " AND m1.AD_Client_ID=?" // #1
|
||||
// Not existing Inv Matches
|
||||
+ " AND NOT EXISTS (SELECT * FROM M_MatchInv mi "
|
||||
+ "WHERE mi.C_InvoiceLine_ID=m1.C_InvoiceLine_ID AND mi.M_InOutLine_ID=m2.M_InOutLine_ID)";
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_AD_Client_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
BigDecimal qty1 = rs.getBigDecimal(8);
|
||||
BigDecimal qty2 = rs.getBigDecimal(9);
|
||||
BigDecimal Qty = qty1.min(qty2);
|
||||
if (Qty.equals(Env.ZERO))
|
||||
continue;
|
||||
Timestamp dateTrx1 = rs.getTimestamp(6);
|
||||
Timestamp dateTrx2 = rs.getTimestamp(7);
|
||||
Timestamp DateTrx = dateTrx1;
|
||||
if (dateTrx1.before(dateTrx2))
|
||||
DateTrx = dateTrx2;
|
||||
//
|
||||
int AD_Client_ID = rs.getInt(1);
|
||||
int AD_Org_ID = rs.getInt(2);
|
||||
int C_InvoiceLine_ID = rs.getInt(3);
|
||||
int M_InOutLine_ID = rs.getInt(4);
|
||||
int M_Product_ID = rs.getInt(5);
|
||||
//
|
||||
if (createMatchInv(AD_Client_ID, AD_Org_ID,
|
||||
M_InOutLine_ID, C_InvoiceLine_ID,
|
||||
M_Product_ID, DateTrx, Qty))
|
||||
counter++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "match", e);
|
||||
}
|
||||
log.fine("Matcher.match - Client_ID=" + m_AD_Client_ID
|
||||
+ ", Records created=" + counter);
|
||||
return counter;
|
||||
} // match
|
||||
|
||||
/**
|
||||
* Create MatchInv record
|
||||
* @param AD_Client_ID Client
|
||||
* @param AD_Org_ID Org
|
||||
* @param M_InOutLine_ID Receipt
|
||||
* @param C_InvoiceLine_ID Invoice
|
||||
* @param M_Product_ID Product
|
||||
* @param DateTrx Date
|
||||
* @param Qty Qty
|
||||
* @return true if record created
|
||||
*/
|
||||
private boolean createMatchInv (int AD_Client_ID, int AD_Org_ID,
|
||||
int M_InOutLine_ID, int C_InvoiceLine_ID,
|
||||
int M_Product_ID, Timestamp DateTrx, BigDecimal Qty)
|
||||
{
|
||||
log.fine("InvLine=" + C_InvoiceLine_ID + ",Rec=" + M_InOutLine_ID + ", Qty=" + Qty + ", " + DateTrx);
|
||||
|
||||
// MMatchInv inv = new MMatchInv ();
|
||||
int M_MatchInv_ID = DB.getNextID (AD_Client_ID, "M_MatchInv", m_trxName);
|
||||
//
|
||||
StringBuffer sql = new StringBuffer("INSERT INTO M_MatchInv ("
|
||||
+ "M_MatchInv_ID, "
|
||||
+ "AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy, "
|
||||
+ "M_InOutLine_ID,C_InvoiceLine_ID, "
|
||||
+ "M_Product_ID,DateTrx,Qty, "
|
||||
+ "Processing,Processed,Posted) VALUES (")
|
||||
.append(M_MatchInv_ID).append(", ")
|
||||
.append(AD_Client_ID).append(",").append(AD_Org_ID).append(",'Y',SysDate,0,SysDate,0, ")
|
||||
.append(M_InOutLine_ID).append(",").append(C_InvoiceLine_ID).append(", ")
|
||||
.append(M_Product_ID).append(",").append(DB.TO_DATE(DateTrx,true)).append(",").append(Qty)
|
||||
.append(", 'N','Y','N')");
|
||||
int no = DB.executeUpdate(sql.toString(), m_trxName);
|
||||
return no == 1;
|
||||
} // createMatchInv
|
||||
|
||||
} // Matcher
|
|
@ -0,0 +1,390 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.acct;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Product Costing Information.
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: ProductInfo.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class ProductInfo
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param M_Product_ID Product
|
||||
* @param trxName transcation
|
||||
*/
|
||||
public ProductInfo (int M_Product_ID, String trxName)
|
||||
{
|
||||
m_trxName = trxName;
|
||||
init (M_Product_ID);
|
||||
} // ProductInfo
|
||||
|
||||
/** The Product Key */
|
||||
private int m_M_Product_ID = 0;
|
||||
/** Transaction */
|
||||
private String m_trxName = null;
|
||||
|
||||
// Product Info
|
||||
private int m_AD_Client_ID = 0;
|
||||
private int m_AD_Org_ID = 0;
|
||||
|
||||
private String m_productType = null;
|
||||
private String m_ProductCategory = null;
|
||||
|
||||
private boolean m_isBOM = false;
|
||||
private boolean m_isStocked = true;
|
||||
|
||||
private int m_C_RevenueRecognition_ID = 0;
|
||||
|
||||
private int m_C_UOM_ID = 0;
|
||||
private BigDecimal m_qty = Env.ZERO;
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger (getClass());
|
||||
|
||||
/**
|
||||
* Get Product Info (Service, Revenue Recognition).
|
||||
* automatically called by constructor
|
||||
* @param M_Product_ID Product
|
||||
*/
|
||||
private void init (int M_Product_ID)
|
||||
{
|
||||
m_M_Product_ID = M_Product_ID;
|
||||
if (m_M_Product_ID == 0)
|
||||
return;
|
||||
|
||||
String sql = "SELECT p.ProductType, pc.Value, " // 1..2
|
||||
+ "p.C_RevenueRecognition_ID,p.C_UOM_ID, " // 3..4
|
||||
+ "p.AD_Client_ID,p.AD_Org_ID, " // 5..6
|
||||
+ "p.IsBOM, p.IsStocked " // 7..8
|
||||
+ "FROM M_Product_Category pc"
|
||||
+ " INNER JOIN M_Product p ON (pc.M_Product_Category_ID=p.M_Product_Category_ID) "
|
||||
+ "WHERE p.M_Product_ID=?"; // #1
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_M_Product_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
m_productType = rs.getString(1);
|
||||
m_ProductCategory = rs.getString(2);
|
||||
m_C_RevenueRecognition_ID = rs.getInt(3);
|
||||
m_C_UOM_ID = rs.getInt(4);
|
||||
// reference
|
||||
m_AD_Client_ID = rs.getInt(5);
|
||||
m_AD_Org_ID = rs.getInt(6);
|
||||
//
|
||||
m_isBOM = "Y".equals(rs.getString(7));
|
||||
m_isStocked = "Y".equals(rs.getString(8));
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
} // init
|
||||
|
||||
/**
|
||||
* Is Product/Item
|
||||
* @return true if product
|
||||
*/
|
||||
public boolean isProduct()
|
||||
{
|
||||
return MProduct.PRODUCTTYPE_Item.equals(m_productType);
|
||||
} // isProduct
|
||||
|
||||
/**
|
||||
* Is it a BOM
|
||||
* @return true if BOM
|
||||
*/
|
||||
public boolean isBOM()
|
||||
{
|
||||
return m_isBOM;
|
||||
} // isBOM
|
||||
|
||||
/**
|
||||
* Is it stocked
|
||||
* @return true if stocked
|
||||
*/
|
||||
public boolean isStocked()
|
||||
{
|
||||
return m_isStocked;
|
||||
} // isStocked
|
||||
|
||||
/**
|
||||
* Is Service
|
||||
* @return true if service
|
||||
*/
|
||||
public boolean isService()
|
||||
{
|
||||
return MProduct.PRODUCTTYPE_Service.equals(m_productType);
|
||||
} // isService
|
||||
|
||||
/**
|
||||
* Get Product Category (Value)
|
||||
* @return M_Product_Category_ID
|
||||
*/
|
||||
public String getProductCategory()
|
||||
{
|
||||
return m_ProductCategory;
|
||||
} // getProductCategory
|
||||
|
||||
/**
|
||||
* Has Revenue Recognition
|
||||
* @return true if product/service has revenue recognition
|
||||
*/
|
||||
public boolean isRevenueRecognition()
|
||||
{
|
||||
return m_C_RevenueRecognition_ID != 0;
|
||||
} // isRevenueRecognition
|
||||
|
||||
/**
|
||||
* Get Revenue Recognition
|
||||
* @return C_RevenueRecognition_ID
|
||||
*/
|
||||
public int getC_RevenueRecognition_ID()
|
||||
{
|
||||
return m_C_RevenueRecognition_ID;
|
||||
} // getC_RevenueRecognition_ID
|
||||
|
||||
/**
|
||||
* Quantity UOM
|
||||
* @return C_UOM_ID
|
||||
*/
|
||||
public int getC_UOM_ID()
|
||||
{
|
||||
return m_C_UOM_ID;
|
||||
} // getC_UOM_ID
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Set Quantity in Storage UOM
|
||||
* @param qty quantity
|
||||
*/
|
||||
public void setQty (BigDecimal qty)
|
||||
{
|
||||
m_qty = qty;
|
||||
} // setQty
|
||||
|
||||
/**
|
||||
* Set Quantity in UOM
|
||||
* @param qty quantity
|
||||
* @param C_UOM_ID UOM
|
||||
*/
|
||||
public void setQty (BigDecimal qty, int C_UOM_ID)
|
||||
{
|
||||
m_qty = MUOMConversion.convert (C_UOM_ID, m_C_UOM_ID, qty, true); // StdPrecision
|
||||
if (qty != null && m_qty == null) // conversion error
|
||||
{
|
||||
log.severe ("Conversion error - set to " + qty);
|
||||
m_qty = qty;
|
||||
}
|
||||
} // setQty
|
||||
|
||||
/**
|
||||
* Get Qty in Storage UOM
|
||||
* @return qty
|
||||
*/
|
||||
public BigDecimal getQty()
|
||||
{
|
||||
return m_qty;
|
||||
} // getQty
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update/Create initial Cost Record.
|
||||
* Check first for Purchase Price List,
|
||||
* then Product Purchase Costs
|
||||
* and then Price List
|
||||
* @param as accounting schema
|
||||
* @param create create record
|
||||
* @return costs
|
||||
*/
|
||||
private BigDecimal updateCosts (MAcctSchema as, boolean create)
|
||||
{
|
||||
// Create Zero Record
|
||||
if (create)
|
||||
{
|
||||
StringBuffer sql = new StringBuffer ("INSERT INTO M_Product_Costing "
|
||||
+ "(M_Product_ID,C_AcctSchema_ID,"
|
||||
+ " AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,"
|
||||
+ " CurrentCostPrice,CostStandard,FutureCostPrice,"
|
||||
+ " CostStandardPOQty,CostStandardPOAmt,CostStandardCumQty,CostStandardCumAmt,"
|
||||
+ " CostAverage,CostAverageCumQty,CostAverageCumAmt,"
|
||||
+ " PriceLastPO,PriceLastInv, TotalInvQty,TotalInvAmt) "
|
||||
+ "VALUES (");
|
||||
sql.append(m_M_Product_ID).append(",").append(as.getC_AcctSchema_ID()).append(",")
|
||||
.append(m_AD_Client_ID).append(",").append(m_AD_Org_ID).append(",")
|
||||
.append("'Y',SysDate,0,SysDate,0, 0,0,0, 0,0,0,0, 0,0,0, 0,0, 0,0)");
|
||||
int no = DB.executeUpdate(sql.toString(), m_trxName);
|
||||
if (no == 1)
|
||||
log.fine("CostingCreated");
|
||||
}
|
||||
|
||||
// Try to find non ZERO Price
|
||||
String costSource = "PriceList-PO";
|
||||
BigDecimal costs = getPriceList (as, true);
|
||||
if (costs == null || costs.equals(Env.ZERO))
|
||||
{
|
||||
costSource = "PO Cost";
|
||||
costs = getPOCost(as);
|
||||
}
|
||||
if (costs == null || costs.equals(Env.ZERO))
|
||||
{
|
||||
costSource = "PriceList";
|
||||
costs = getPriceList (as, false);
|
||||
}
|
||||
|
||||
// if not found use $1 (to be able to do material transactions)
|
||||
if (costs == null || costs.equals(Env.ZERO))
|
||||
{
|
||||
costSource = "Not Found";
|
||||
costs = new BigDecimal("1");
|
||||
}
|
||||
|
||||
// update current costs
|
||||
StringBuffer sql = new StringBuffer ("UPDATE M_Product_Costing ");
|
||||
sql.append("SET CurrentCostPrice=").append(costs)
|
||||
.append(" WHERE M_Product_ID=").append(m_M_Product_ID)
|
||||
.append(" AND C_AcctSchema_ID=").append(as.getC_AcctSchema_ID());
|
||||
int no = DB.executeUpdate(sql.toString(), m_trxName);
|
||||
if (no == 1)
|
||||
log.fine(costSource + " - " + costs);
|
||||
return costs;
|
||||
} // createCosts
|
||||
|
||||
/**
|
||||
* Get PO Price from PriceList - and convert it to AcctSchema Currency
|
||||
* @param as accounting schema
|
||||
* @param onlyPOPriceList use only PO price list
|
||||
* @return po price
|
||||
*/
|
||||
private BigDecimal getPriceList (MAcctSchema as, boolean onlyPOPriceList)
|
||||
{
|
||||
StringBuffer sql = new StringBuffer (
|
||||
"SELECT pl.C_Currency_ID, pp.PriceList, pp.PriceStd, pp.PriceLimit "
|
||||
+ "FROM M_PriceList pl, M_PriceList_Version plv, M_ProductPrice pp "
|
||||
+ "WHERE pl.M_PriceList_ID = plv.M_PriceList_ID"
|
||||
+ " AND plv.M_PriceList_Version_ID = pp.M_PriceList_Version_ID"
|
||||
+ " AND pp.M_Product_ID=?");
|
||||
if (onlyPOPriceList)
|
||||
sql.append(" AND pl.IsSOPriceList='N'");
|
||||
sql.append(" ORDER BY pl.IsSOPriceList ASC, plv.ValidFrom DESC");
|
||||
int C_Currency_ID = 0;
|
||||
BigDecimal PriceList = null;
|
||||
BigDecimal PriceStd = null;
|
||||
BigDecimal PriceLimit = null;
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
|
||||
pstmt.setInt(1, m_M_Product_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
C_Currency_ID = rs.getInt(1);
|
||||
PriceList = rs.getBigDecimal(2);
|
||||
PriceStd = rs.getBigDecimal(3);
|
||||
PriceLimit = rs.getBigDecimal(4);
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql.toString(), e);
|
||||
}
|
||||
// nothing found
|
||||
if (C_Currency_ID == 0)
|
||||
return null;
|
||||
|
||||
BigDecimal price = PriceLimit; // best bet
|
||||
if (price == null || price.equals(Env.ZERO))
|
||||
price = PriceStd;
|
||||
if (price == null || price.equals(Env.ZERO))
|
||||
price = PriceList;
|
||||
// Convert
|
||||
if (price != null && !price.equals(Env.ZERO))
|
||||
price = MConversionRate.convert (as.getCtx(),
|
||||
price, C_Currency_ID, as.getC_Currency_ID(),
|
||||
as.getAD_Client_ID(), 0);
|
||||
return price;
|
||||
} // getPOPrice
|
||||
|
||||
/**
|
||||
* Get PO Cost from Purchase Info - and convert it to AcctSchema Currency
|
||||
* @param as accounting schema
|
||||
* @return po cost
|
||||
*/
|
||||
private BigDecimal getPOCost (MAcctSchema as)
|
||||
{
|
||||
String sql = "SELECT C_Currency_ID, PriceList,PricePO,PriceLastPO "
|
||||
+ "FROM M_Product_PO WHERE M_Product_ID=? "
|
||||
+ "ORDER BY IsCurrentVendor DESC";
|
||||
|
||||
int C_Currency_ID = 0;
|
||||
BigDecimal PriceList = null;
|
||||
BigDecimal PricePO = null;
|
||||
BigDecimal PriceLastPO = null;
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_M_Product_ID);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (rs.next())
|
||||
{
|
||||
C_Currency_ID = rs.getInt(1);
|
||||
PriceList = rs.getBigDecimal(2);
|
||||
PricePO = rs.getBigDecimal(3);
|
||||
PriceLastPO = rs.getBigDecimal(4);
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
// nothing found
|
||||
if (C_Currency_ID == 0)
|
||||
return null;
|
||||
|
||||
BigDecimal cost = PriceLastPO; // best bet
|
||||
if (cost == null || cost.equals(Env.ZERO))
|
||||
cost = PricePO;
|
||||
if (cost == null || cost.equals(Env.ZERO))
|
||||
cost = PriceList;
|
||||
// Convert - standard precision!! - should be costing precision
|
||||
if (cost != null && !cost.equals(Env.ZERO))
|
||||
cost = MConversionRate.convert (as.getCtx(),
|
||||
cost, C_Currency_ID, as.getC_Currency_ID(), m_AD_Client_ID, m_AD_Org_ID);
|
||||
return cost;
|
||||
} // getPOCost
|
||||
|
||||
} // ProductInfo
|
|
@ -0,0 +1,118 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms version 2 of the GNU General Public License as published
|
||||
* by the Free Software Foundation. This program is distributed in the hope
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
* You may reach us at: ComPiere, Inc. - http://www.adempiere.org/license.html
|
||||
* 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
|
||||
*****************************************************************************/
|
||||
package org.compiere.ldap;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.ldap.*;
|
||||
import org.compiere.util.*;
|
||||
import com.sun.jndi.ldap.*;
|
||||
|
||||
/**
|
||||
* LDAP Connection Handler
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: LdapConnectionHandler.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
|
||||
*/
|
||||
public class LdapConnectionHandler extends Thread
|
||||
{
|
||||
/**
|
||||
* Ldap Connection Handler
|
||||
* @param socket server socket
|
||||
*/
|
||||
public LdapConnectionHandler(Socket socket)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_socket = socket;
|
||||
m_socket.setTcpNoDelay(true); // should not be required
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "", e);
|
||||
} // no timeout
|
||||
} // LdapConnectionHandler
|
||||
|
||||
/** Socket */
|
||||
private Socket m_socket = null;
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger (LdapConnectionHandler.class);
|
||||
|
||||
|
||||
/**
|
||||
* Do Work
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_socket == null || m_socket.isClosed())
|
||||
return;
|
||||
|
||||
boolean activeSession = true;
|
||||
while (activeSession)
|
||||
{
|
||||
InputStream in = m_socket.getInputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(m_socket.getOutputStream());
|
||||
// Read
|
||||
byte[] buffer = new byte[512];
|
||||
int length = in.read(buffer, 0, 512);
|
||||
|
||||
LdapMessage msg = new LdapMessage (buffer, length);
|
||||
if (msg.getOperation() == LdapMessage.UNBIND_REQUEST)
|
||||
{
|
||||
activeSession = false;
|
||||
out.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
LdapResult result = new LdapResult ();
|
||||
byte[] bytes = result.bindResponse();
|
||||
//
|
||||
out.write(bytes);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_socket.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.WARNING, "Socket", e);
|
||||
}
|
||||
m_socket = null;
|
||||
} // run
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ("LdapConnectionHandler[");
|
||||
sb.append (hashCode()).append ("]");
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
} // LdapConnectionHandler
|
|
@ -0,0 +1,172 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms version 2 of the GNU General Public License as published
|
||||
* by the Free Software Foundation. This program is distributed in the hope
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
* You may reach us at: ComPiere, Inc. - http://www.adempiere.org/license.html
|
||||
* 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
|
||||
*****************************************************************************/
|
||||
package org.compiere.ldap;
|
||||
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
import com.sun.jndi.ldap.*;
|
||||
|
||||
/**
|
||||
* Ldap Message
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: LdapMessage.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
|
||||
*/
|
||||
public class LdapMessage
|
||||
{
|
||||
/**
|
||||
* Ldap Message
|
||||
* @param data BER data
|
||||
* @param length Ber data length
|
||||
*/
|
||||
public LdapMessage (byte[] data, int length)
|
||||
{
|
||||
try
|
||||
{
|
||||
decode(data, length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, data.toString(), e);
|
||||
}
|
||||
} // LdapMessage
|
||||
|
||||
/**
|
||||
LDAPMessage ::= SEQUENCE {
|
||||
messageID MessageID,
|
||||
protocolOp CHOICE {
|
||||
bindRequest BindRequest,
|
||||
bindResponse BindResponse,
|
||||
unbindRequest UnbindRequest,
|
||||
searchRequest SearchRequest,
|
||||
searchResEntry SearchResultEntry,
|
||||
searchResDone SearchResultDone,
|
||||
searchResRef SearchResultReference,
|
||||
modifyRequest ModifyRequest,
|
||||
modifyResponse ModifyResponse,
|
||||
addRequest AddRequest,
|
||||
addResponse AddResponse,
|
||||
delRequest DelRequest,
|
||||
delResponse DelResponse,
|
||||
modDNRequest ModifyDNRequest,
|
||||
modDNResponse ModifyDNResponse,
|
||||
compareRequest CompareRequest,
|
||||
compareResponse CompareResponse,
|
||||
abandonRequest AbandonRequest,
|
||||
extendedReq ExtendedRequest,
|
||||
extendedResp ExtendedResponse },
|
||||
controls [0] Controls OPTIONAL }
|
||||
**/
|
||||
|
||||
static public final int BIND_REQUEST = 0;
|
||||
static public final int BIND_RESPONSE = 1;
|
||||
static public final int UNBIND_REQUEST = 2;
|
||||
static public final int SEARCH_REQUEST = 3;
|
||||
static public final int SEARCH_RESENTRY = 4;
|
||||
static public final int SEARCH_RESDONE = 5;
|
||||
static public final int MODIFY_REQUEST = 6;
|
||||
static public final int MODIFY_RESPONSE = 7;
|
||||
static public final int ADD_REQUEST = 8;
|
||||
static public final int ADD_RESPONSE = 9;
|
||||
static public final int DEL_REQUEST = 10;
|
||||
static public final int DEL_RESPONSE = 11;
|
||||
static public final int MODDN_REQUEST = 12;
|
||||
static public final int MODDN_RESPONSE = 13;
|
||||
static public final int COMPARE_REQUEST = 14;
|
||||
static public final int COMPARE_RESPONSE = 15;
|
||||
static public final int ABANDON_REQUEST = 16;
|
||||
static public final int EXTENDED_REQUEST = 17;
|
||||
static public final int EXTENDED_RESPONSE = 18;
|
||||
|
||||
static public final int[] PROTOCOL_OP = {
|
||||
BIND_REQUEST, BIND_RESPONSE, UNBIND_REQUEST,
|
||||
SEARCH_REQUEST, SEARCH_RESENTRY, SEARCH_RESDONE,
|
||||
MODIFY_REQUEST, MODIFY_RESPONSE, ADD_REQUEST, ADD_RESPONSE,
|
||||
DEL_REQUEST, DEL_RESPONSE, MODDN_REQUEST, MODDN_RESPONSE,
|
||||
COMPARE_REQUEST, COMPARE_RESPONSE, ABANDON_REQUEST,
|
||||
EXTENDED_REQUEST, EXTENDED_RESPONSE};
|
||||
|
||||
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger (LdapMessage.class);
|
||||
/** Protocol Operation */
|
||||
private int m_protocolOp = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Decode Message
|
||||
* @param data data
|
||||
* @param length length
|
||||
* @throws Exception
|
||||
*/
|
||||
private void decode (byte[] data, int length) throws Exception
|
||||
{
|
||||
BerDecoder decoder = new BerDecoder(data, 0, length);
|
||||
int left = decoder.bytesLeft();
|
||||
int pos = decoder.getParsePosition();
|
||||
//
|
||||
int seq = decoder.parseSeq(null);
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
int messageID = decoder.parseInt();
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
int peek = decoder.peekByte();
|
||||
m_protocolOp = decoder.parseSeq(PROTOCOL_OP);
|
||||
m_protocolOp -= Ber.ASN_APPLICATION;
|
||||
if (m_protocolOp - Ber.ASN_CONSTRUCTOR >= 0)
|
||||
m_protocolOp -= Ber.ASN_CONSTRUCTOR;
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
// Payload
|
||||
if (m_protocolOp == BIND_REQUEST)
|
||||
{
|
||||
int version = decoder.parseInt();
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
byte[] dn = decoder.parseOctetString(Ber.ASN_OCTET_STR, null);
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
byte[] authentification = decoder.parseOctetString(Ber.ASN_CONTEXT, null);
|
||||
left = decoder.bytesLeft();
|
||||
pos = decoder.getParsePosition();
|
||||
//
|
||||
log.info("#" + messageID + ": bind - version=" + version + ", dn=" + new String(dn)
|
||||
+ ", auth=" + new String (authentification));
|
||||
}
|
||||
else if (m_protocolOp == UNBIND_REQUEST)
|
||||
log.info("#" + messageID + ": unbind");
|
||||
else
|
||||
{
|
||||
log.warning("#" + messageID + ": Unknown Op + " + m_protocolOp);
|
||||
}
|
||||
} // decode
|
||||
|
||||
/**
|
||||
* Get Operation Code
|
||||
* @return protocolOp
|
||||
*/
|
||||
public int getOperation()
|
||||
{
|
||||
return m_protocolOp;
|
||||
} // getOperation
|
||||
|
||||
} // LdapMessage
|
|
@ -0,0 +1,141 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms version 2 of the GNU General Public License as published
|
||||
* by the Free Software Foundation. This program is distributed in the hope
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
* You may reach us at: ComPiere, Inc. - http://www.adempiere.org/license.html
|
||||
* 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
|
||||
*****************************************************************************/
|
||||
package org.compiere.ldap;
|
||||
|
||||
import java.net.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import javax.naming.ldap.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.ldap.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.server.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* LDAP Server
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: LdapProcessor.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
|
||||
*/
|
||||
public class LdapProcessor extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* Ldap Processor (Server)
|
||||
* @param model Ldap Model
|
||||
*/
|
||||
public LdapProcessor (LdapProcessorModel model)
|
||||
{
|
||||
super (model, 300);
|
||||
m_model = model;
|
||||
init();
|
||||
} // LdapProcessor
|
||||
|
||||
/** The Concrete Model */
|
||||
private LdapProcessorModel m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Client info */
|
||||
private MClient m_client = null;
|
||||
/** Server Socket */
|
||||
private ServerSocket m_serverSocket = null;
|
||||
/** Counter */
|
||||
private int m_counter = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Do Work
|
||||
*/
|
||||
protected void doWork()
|
||||
{
|
||||
// Close Socket
|
||||
if (m_serverSocket != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_serverSocket.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
m_counter = 0;
|
||||
//
|
||||
m_summary = new StringBuffer(m_model.toString())
|
||||
.append(" - ");
|
||||
//
|
||||
|
||||
try
|
||||
{
|
||||
m_serverSocket = new ServerSocket(m_model.getLdapPort());
|
||||
log.log(Level.INFO, "Opened Port=" + m_model.getLdapPort());
|
||||
while (!isInterrupted())
|
||||
{
|
||||
Socket socket = m_serverSocket.accept(); // waits for connection
|
||||
log.log(Level.FINE, "Connection on Port=" + m_model.getLdapPort());
|
||||
LdapConnectionHandler handler = new LdapConnectionHandler (socket);
|
||||
handler.start();
|
||||
m_counter++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.WARNING, "Port=" + m_model.getLdapPort(), e);
|
||||
m_summary.append(e.toString());
|
||||
}
|
||||
|
||||
} // doWork
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
try
|
||||
{
|
||||
InitialLdapContext lctx = new InitialLdapContext();
|
||||
// lctx.setRequestControls(critModCtls);
|
||||
// lctx.modifyAttributes(name, mods);
|
||||
Control[] respCtls = lctx.getResponseControls();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
} //
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString()
|
||||
+ "; Counter=" + m_counter;
|
||||
} // getServerInfo
|
||||
|
||||
/**
|
||||
* Test
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Adempiere.startup(true);
|
||||
new LdapProcessor(new LdapProcessorModel(new Properties())).doWork();
|
||||
} // main
|
||||
|
||||
} // LdapProcessor
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms version 2 of the GNU General Public License as published
|
||||
* by the Free Software Foundation. This program is distributed in the hope
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
* You may reach us at: ComPiere, Inc. - http://www.adempiere.org/license.html
|
||||
* 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
|
||||
*****************************************************************************/
|
||||
package org.compiere.ldap;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import org.compiere.model.*;
|
||||
|
||||
/**
|
||||
* Interim LDAP Server Model
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: LdapProcessorModel.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
|
||||
*/
|
||||
public class LdapProcessorModel implements AdempiereProcessor
|
||||
{
|
||||
/**
|
||||
* Ldap Processor Model
|
||||
* @param ctx context
|
||||
*/
|
||||
public LdapProcessorModel (Properties ctx)
|
||||
{
|
||||
m_ctx = ctx;
|
||||
}
|
||||
// Properties
|
||||
private Properties m_ctx = null;
|
||||
|
||||
private Timestamp m_dateNextRun;
|
||||
private Timestamp m_dateLastRun;
|
||||
|
||||
|
||||
public int getLdapPort()
|
||||
{
|
||||
return 389;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer (getName());
|
||||
sb.append (";Port=").append (getLdapPort());
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* getAD_Client_ID
|
||||
* @see org.compiere.model.AdempiereProcessor#getAD_Client_ID()
|
||||
* @return 0
|
||||
*/
|
||||
public int getAD_Client_ID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* getName
|
||||
* @see org.compiere.model.AdempiereProcessor#getName()
|
||||
* @return name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return "Adempiere LDAP Server";
|
||||
}
|
||||
/**
|
||||
* getDescription
|
||||
* @see org.compiere.model.AdempiereProcessor#getDescription()
|
||||
* @return -
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
/**
|
||||
* Get Ctx
|
||||
* @return context
|
||||
*/
|
||||
public Properties getCtx()
|
||||
{
|
||||
return m_ctx;
|
||||
}
|
||||
/**
|
||||
* GetFrequencyType
|
||||
* @see org.compiere.model.AdempiereProcessor#getFrequencyType()
|
||||
* @return min
|
||||
*/
|
||||
public String getFrequencyType()
|
||||
{
|
||||
return MRequestProcessor.FREQUENCYTYPE_Minute;
|
||||
}
|
||||
/**
|
||||
* getFrequency
|
||||
* @see org.compiere.model.AdempiereProcessor#getFrequency()
|
||||
* @return 1
|
||||
*/
|
||||
public int getFrequency()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Unique Server ID
|
||||
* @return id
|
||||
*/
|
||||
public String getServerID()
|
||||
{
|
||||
return "Ldap";
|
||||
}
|
||||
|
||||
public Timestamp getDateNextRun(boolean requery)
|
||||
{
|
||||
return m_dateNextRun;
|
||||
}
|
||||
|
||||
public void setDateNextRun(Timestamp dateNextWork)
|
||||
{
|
||||
m_dateNextRun = dateNextWork;
|
||||
}
|
||||
|
||||
public Timestamp getDateLastRun()
|
||||
{
|
||||
return m_dateLastRun;
|
||||
}
|
||||
|
||||
public void setDateLastRun(Timestamp dateLastRun)
|
||||
{
|
||||
m_dateLastRun = dateLastRun;
|
||||
}
|
||||
|
||||
public boolean save()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public AdempiereProcessorLog[] getLogs()
|
||||
{
|
||||
return new AdempiereProcessorLog[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms version 2 of the GNU General Public License as published
|
||||
* by the Free Software Foundation. This program is distributed in the hope
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
* You may reach us at: ComPiere, Inc. - http://www.adempiere.org/license.html
|
||||
* 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA or info@adempiere.org
|
||||
*****************************************************************************/
|
||||
package org.compiere.ldap;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
import com.sun.jndi.ldap.*;
|
||||
|
||||
/**
|
||||
* Ldap Wire Response
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: LdapResult.java,v 1.1 2006/10/09 00:23:16 jjanke Exp $
|
||||
*/
|
||||
public class LdapResult
|
||||
{
|
||||
|
||||
public LdapResult()
|
||||
{
|
||||
super ();
|
||||
} // LdapResult
|
||||
|
||||
/**
|
||||
LDAPResult ::= SEQUENCE {
|
||||
resultCode ENUMERATED {
|
||||
success (0),
|
||||
operationsError (1),
|
||||
protocolError (2),
|
||||
timeLimitExceeded (3),
|
||||
sizeLimitExceeded (4),
|
||||
compareFalse (5),
|
||||
compareTrue (6),
|
||||
|
||||
authMethodNotSupported (7),
|
||||
strongAuthRequired (8),
|
||||
-- 9 reserved --
|
||||
referral (10), -- new
|
||||
adminLimitExceeded (11), -- new
|
||||
unavailableCriticalExtension (12), -- new
|
||||
confidentialityRequired (13), -- new
|
||||
saslBindInProgress (14), -- new
|
||||
noSuchAttribute (16),
|
||||
undefinedAttributeType (17),
|
||||
inappropriateMatching (18),
|
||||
constraintViolation (19),
|
||||
attributeOrValueExists (20),
|
||||
invalidAttributeSyntax (21),
|
||||
noSuchObject (32),
|
||||
aliasProblem (33),
|
||||
invalidDNSyntax (34),
|
||||
-- 35 reserved for undefined isLeaf --
|
||||
aliasDereferencingProblem (36),
|
||||
-- 37-47 unused --
|
||||
inappropriateAuthentication (48),
|
||||
invalidCredentials (49),
|
||||
insufficientAccessRights (50),
|
||||
busy (51),
|
||||
unavailable (52),
|
||||
unwillingToPerform (53),
|
||||
loopDetect (54),
|
||||
-- 55-63 unused --
|
||||
namingViolation (64),
|
||||
objectClassViolation (65),
|
||||
notAllowedOnNonLeaf (66),
|
||||
notAllowedOnRDN (67),
|
||||
entryAlreadyExists (68),
|
||||
objectClassModsProhibited (69),
|
||||
-- 70 reserved for CLDAP --
|
||||
affectsMultipleDSAs (71), -- new
|
||||
-- 72-79 unused --
|
||||
other (80) },
|
||||
-- 81-90 reserved for APIs --
|
||||
matchedDN LDAPDN,
|
||||
errorMessage LDAPString,
|
||||
referral [3] Referral OPTIONAL }
|
||||
**/
|
||||
|
||||
/** Encoder */
|
||||
private BerEncoder m_encoder = new BerEncoder();
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger (LdapResult.class);
|
||||
|
||||
/**
|
||||
* Bind Response
|
||||
* @return reponse
|
||||
*/
|
||||
public byte[] bindResponse()
|
||||
{
|
||||
try
|
||||
{
|
||||
/**
|
||||
m_encoder.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
|
||||
for (int i = 0; i < sortKeys.length; i++) {
|
||||
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
|
||||
ber.encodeString(sortKeys[i].getAttributeID(), true); // v3
|
||||
if ((matchingRule = sortKeys[i].getMatchingRuleID()) != null) {
|
||||
ber.encodeString(matchingRule, (Ber.ASN_CONTEXT | 0), true);
|
||||
}
|
||||
if (! sortKeys[i].isAscending()) {
|
||||
ber.encodeBoolean(true, (Ber.ASN_CONTEXT | 1));
|
||||
}
|
||||
ber.endSeq();
|
||||
}
|
||||
*/
|
||||
// payload
|
||||
m_encoder.beginSeq(Ber.ASN_APPLICATION | LdapMessage.BIND_RESPONSE);
|
||||
// Response
|
||||
m_encoder.encodeInt(0); // success
|
||||
m_encoder.encodeOctetString("cn=testCN".getBytes(), 0); // matched DN
|
||||
m_encoder.encodeOctetString("".getBytes(), 0); // error mag
|
||||
// referral
|
||||
// sasl
|
||||
//
|
||||
m_encoder.endSeq();
|
||||
log.info("Success");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "", e);
|
||||
}
|
||||
return getResult();
|
||||
} // bindResponse
|
||||
|
||||
/**
|
||||
* Get BER Result as byte array
|
||||
* @return byte array
|
||||
*/
|
||||
public byte[] getResult()
|
||||
{
|
||||
return m_encoder.getTrimmedBuf();
|
||||
} // getResult
|
||||
|
||||
} // LdapResult
|
|
@ -0,0 +1,172 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.acct.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Accounting Processor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AcctProcessor.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class AcctProcessor extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* Accounting Processor
|
||||
* @param model model
|
||||
*/
|
||||
public AcctProcessor (MAcctProcessor model)
|
||||
{
|
||||
super (model, 30); // 30 seconds delay
|
||||
m_model = model;
|
||||
m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
|
||||
} // AcctProcessor
|
||||
|
||||
/** The Concrete Model */
|
||||
private MAcctProcessor m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Client onfo */
|
||||
private MClient m_client = null;
|
||||
/** Accounting Schemata */
|
||||
private MAcctSchema[] m_ass = null;
|
||||
|
||||
/**
|
||||
* Work
|
||||
*/
|
||||
protected void doWork ()
|
||||
{
|
||||
m_summary = new StringBuffer();
|
||||
// Get Schemata
|
||||
if (m_model.getC_AcctSchema_ID() == 0)
|
||||
m_ass = MAcctSchema.getClientAcctSchema(getCtx(), m_model.getAD_Client_ID());
|
||||
else // only specific accounting schema
|
||||
m_ass = new MAcctSchema[] {new MAcctSchema (getCtx(), m_model.getC_AcctSchema_ID(), null)};
|
||||
//
|
||||
postSession();
|
||||
MCost.create(m_client);
|
||||
//
|
||||
int no = m_model.deleteLog();
|
||||
m_summary.append("Logs deleted=").append(no);
|
||||
//
|
||||
MAcctProcessorLog pLog = new MAcctProcessorLog(m_model, m_summary.toString());
|
||||
pLog.setReference("#" + String.valueOf(p_runCount)
|
||||
+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
|
||||
pLog.save();
|
||||
} // doWork
|
||||
|
||||
/**
|
||||
* Post Session
|
||||
*/
|
||||
private void postSession()
|
||||
{
|
||||
for (int i = 0; i < Doc.documentsTableID.length; i++)
|
||||
{
|
||||
int AD_Table_ID = Doc.documentsTableID[i];
|
||||
String TableName = Doc.documentsTableName[i];
|
||||
// Post only special documents
|
||||
if (m_model.getAD_Table_ID() != 0
|
||||
&& m_model.getAD_Table_ID() != AD_Table_ID)
|
||||
continue;
|
||||
// SELECT * FROM table
|
||||
StringBuffer sql = new StringBuffer ("SELECT * FROM ").append(TableName)
|
||||
.append(" WHERE AD_Client_ID=?")
|
||||
.append(" AND Processed='Y' AND Posted='N' AND IsActive='Y'")
|
||||
.append(" ORDER BY Created");
|
||||
//
|
||||
int count = 0;
|
||||
int countError = 0;
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql.toString(), null);
|
||||
pstmt.setInt(1, m_model.getAD_Client_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (!isInterrupted() && rs.next())
|
||||
{
|
||||
count++;
|
||||
boolean ok = true;
|
||||
try
|
||||
{
|
||||
Doc doc = Doc.get (m_ass, AD_Table_ID, rs, null);
|
||||
if (doc == null)
|
||||
{
|
||||
log.severe(getName() + ": No Doc for " + TableName);
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
String error = doc.post(false, false); // post no force/repost
|
||||
ok = error == null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, getName() + ": " + TableName, e);
|
||||
ok = false;
|
||||
}
|
||||
if (!ok)
|
||||
countError++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql.toString(), e);
|
||||
}
|
||||
if (pstmt != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
pstmt.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
//
|
||||
if (count > 0)
|
||||
{
|
||||
m_summary.append(TableName).append("=").append(count);
|
||||
if (countError > 0)
|
||||
m_summary.append("(Errors=").append(countError).append(")");
|
||||
m_summary.append(" - ");
|
||||
log.finer(getName() + ": " + m_summary.toString());
|
||||
}
|
||||
else
|
||||
log.finer(getName() + ": " + TableName + " - no work");
|
||||
}
|
||||
} // postSession
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString();
|
||||
} // getServerInfo
|
||||
|
||||
} // AcctProcessor
|
|
@ -0,0 +1,388 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.ldap.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
import org.compiere.wf.*;
|
||||
|
||||
/**
|
||||
* Adempiere Server Base
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AdempiereServer.java,v 1.3 2006/10/09 00:23:26 jjanke Exp $
|
||||
*/
|
||||
public abstract class AdempiereServer extends Thread
|
||||
{
|
||||
/**
|
||||
* Create New Server Thead
|
||||
* @param model model
|
||||
* @return server tread or null
|
||||
*/
|
||||
public static AdempiereServer create (AdempiereProcessor model)
|
||||
{
|
||||
if (model instanceof MRequestProcessor)
|
||||
return new RequestProcessor ((MRequestProcessor)model);
|
||||
if (model instanceof MWorkflowProcessor)
|
||||
return new WorkflowProcessor ((MWorkflowProcessor)model);
|
||||
if (model instanceof MAcctProcessor)
|
||||
return new AcctProcessor ((MAcctProcessor)model);
|
||||
if (model instanceof MAlertProcessor)
|
||||
return new AlertProcessor ((MAlertProcessor)model);
|
||||
if (model instanceof MScheduler)
|
||||
return new Scheduler ((MScheduler)model);
|
||||
if (model instanceof LdapProcessorModel)
|
||||
return new LdapProcessor((LdapProcessorModel)model);
|
||||
//
|
||||
throw new IllegalArgumentException("Unknown Processor");
|
||||
} // create
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Server Base Class
|
||||
* @param model model
|
||||
* @param initialNap delay time running in sec
|
||||
*/
|
||||
protected AdempiereServer (AdempiereProcessor model, int initialNap)
|
||||
{
|
||||
super (AdempiereServerGroup.get(), null, model.getName(), 0);
|
||||
p_model = model;
|
||||
m_ctx = new Properties(model.getCtx());
|
||||
if (p_system == null)
|
||||
p_system = MSystem.get(m_ctx);
|
||||
p_client = MClient.get(m_ctx);
|
||||
Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID());
|
||||
m_initialNap = initialNap;
|
||||
// log.info(model.getName() + " - " + getThreadGroup());
|
||||
} // ServerBase
|
||||
|
||||
/** The Processor Model */
|
||||
protected AdempiereProcessor p_model;
|
||||
/** Initial nap is seconds */
|
||||
private int m_initialNap = 0;
|
||||
|
||||
/** Miliseconds to sleep - 10 Min default */
|
||||
private long m_sleepMS = 600000;
|
||||
/** Sleeping */
|
||||
private volatile boolean m_sleeping = false;
|
||||
/** Server start time */
|
||||
private long m_start = 0;
|
||||
/** Number of Work executions */
|
||||
protected int p_runCount = 0;
|
||||
/** Tine start of work */
|
||||
protected long p_startWork = 0;
|
||||
/** Number MS of last Run */
|
||||
private long m_runLastMS = 0;
|
||||
/** Number of MS total */
|
||||
private long m_runTotalMS = 0;
|
||||
/** When to run next */
|
||||
private long m_nextWork = 0;
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
/** Context */
|
||||
private Properties m_ctx = null;
|
||||
/** System */
|
||||
protected static MSystem p_system = null;
|
||||
/** Client */
|
||||
protected MClient p_client = null;
|
||||
|
||||
/**
|
||||
* Get Server Context
|
||||
* @return context
|
||||
*/
|
||||
public Properties getCtx()
|
||||
{
|
||||
return m_ctx;
|
||||
} // getCtx
|
||||
|
||||
/**
|
||||
* @return Returns the sleepMS.
|
||||
*/
|
||||
public long getSleepMS ()
|
||||
{
|
||||
return m_sleepMS;
|
||||
} // getSleepMS
|
||||
|
||||
|
||||
/**
|
||||
* Sleep for set time
|
||||
* @return true if not interrupted
|
||||
*/
|
||||
public boolean sleep()
|
||||
{
|
||||
if (isInterrupted())
|
||||
{
|
||||
log.info (getName() + ": interrupted");
|
||||
return false;
|
||||
}
|
||||
log.fine(getName() + ": sleeping " + TimeUtil.formatElapsed(m_sleepMS));
|
||||
m_sleeping = true;
|
||||
try
|
||||
{
|
||||
sleep (m_sleepMS);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
log.info (getName() + ": interrupted");
|
||||
m_sleeping = false;
|
||||
return false;
|
||||
}
|
||||
m_sleeping = false;
|
||||
return true;
|
||||
} // sleep
|
||||
|
||||
/**
|
||||
* Run Now
|
||||
*/
|
||||
public void runNow()
|
||||
{
|
||||
log.info(getName());
|
||||
p_startWork = System.currentTimeMillis();
|
||||
doWork();
|
||||
long now = System.currentTimeMillis();
|
||||
// ---------------
|
||||
|
||||
p_runCount++;
|
||||
m_runLastMS = now - p_startWork;
|
||||
m_runTotalMS += m_runLastMS;
|
||||
//
|
||||
p_model.setDateLastRun(new Timestamp(now));
|
||||
p_model.save();
|
||||
//
|
||||
log.fine(getName() + ": " + getStatistics());
|
||||
} // runNow
|
||||
|
||||
/**************************************************************************
|
||||
* Run async
|
||||
*/
|
||||
public void run ()
|
||||
{
|
||||
try
|
||||
{
|
||||
log.fine(getName() + ": pre-nap - " + m_initialNap);
|
||||
sleep (m_initialNap * 1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
log.log(Level.SEVERE, getName() + ": pre-nap interrupted", e);
|
||||
return;
|
||||
}
|
||||
|
||||
m_start = System.currentTimeMillis();
|
||||
while (true)
|
||||
{
|
||||
if (m_nextWork == 0)
|
||||
{
|
||||
Timestamp dateNextRun = getDateNextRun(true);
|
||||
if (dateNextRun != null)
|
||||
m_nextWork = dateNextRun.getTime();
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
if (m_nextWork > now)
|
||||
{
|
||||
m_sleepMS = m_nextWork - now;
|
||||
if (!sleep ())
|
||||
break;
|
||||
}
|
||||
if (isInterrupted())
|
||||
{
|
||||
log.info (getName() + ": interrupted");
|
||||
break;
|
||||
}
|
||||
|
||||
// ---------------
|
||||
p_startWork = System.currentTimeMillis();
|
||||
doWork();
|
||||
now = System.currentTimeMillis();
|
||||
// ---------------
|
||||
|
||||
p_runCount++;
|
||||
m_runLastMS = now - p_startWork;
|
||||
m_runTotalMS += m_runLastMS;
|
||||
//
|
||||
m_sleepMS = calculateSleep();
|
||||
m_nextWork = now + m_sleepMS;
|
||||
//
|
||||
p_model.setDateLastRun(new Timestamp(now));
|
||||
p_model.setDateNextRun(new Timestamp(m_nextWork));
|
||||
p_model.save();
|
||||
//
|
||||
log.fine(getName() + ": " + getStatistics());
|
||||
if (!sleep())
|
||||
break;
|
||||
}
|
||||
m_start = 0;
|
||||
} // run
|
||||
|
||||
/**
|
||||
* Get Run Statistics
|
||||
* @return Statistic info
|
||||
*/
|
||||
public String getStatistics()
|
||||
{
|
||||
return "Run #" + p_runCount
|
||||
+ " - Last=" + TimeUtil.formatElapsed(m_runLastMS)
|
||||
+ " - Total=" + TimeUtil.formatElapsed(m_runTotalMS)
|
||||
+ " - Next " + TimeUtil.formatElapsed(m_nextWork - System.currentTimeMillis());
|
||||
} // getStatistics
|
||||
|
||||
/**
|
||||
* Do the actual Work
|
||||
*/
|
||||
protected abstract void doWork();
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public abstract String getServerInfo();
|
||||
|
||||
/**
|
||||
* Get Unique ID
|
||||
* @return Unique ID
|
||||
*/
|
||||
public String getServerID()
|
||||
{
|
||||
return p_model.getServerID();
|
||||
} // getServerID
|
||||
|
||||
/**
|
||||
* Get the date Next run
|
||||
* @param requery requery database
|
||||
* @return date next run
|
||||
*/
|
||||
public Timestamp getDateNextRun (boolean requery)
|
||||
{
|
||||
return p_model.getDateNextRun(requery);
|
||||
} // getDateNextRun
|
||||
|
||||
/**
|
||||
* Get the date Last run
|
||||
* @return date lext run
|
||||
*/
|
||||
public Timestamp getDateLastRun ()
|
||||
{
|
||||
return p_model.getDateLastRun();
|
||||
} // getDateLastRun
|
||||
|
||||
/**
|
||||
* Get Description
|
||||
* @return Description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return p_model.getDescription();
|
||||
} // getDescription
|
||||
|
||||
/**
|
||||
* Get Model
|
||||
* @return Model
|
||||
*/
|
||||
public AdempiereProcessor getModel()
|
||||
{
|
||||
return p_model;
|
||||
} // getModel
|
||||
|
||||
/**
|
||||
* Calculate Sleep ms
|
||||
* @return miliseconds
|
||||
*/
|
||||
private long calculateSleep ()
|
||||
{
|
||||
String frequencyType = p_model.getFrequencyType();
|
||||
int frequency = p_model.getFrequency();
|
||||
if (frequency < 1)
|
||||
frequency = 1;
|
||||
//
|
||||
long typeSec = 600; // 10 minutes
|
||||
if (frequencyType == null)
|
||||
typeSec = 300; // 5 minutes
|
||||
else if (X_R_RequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType))
|
||||
typeSec = 60;
|
||||
else if (X_R_RequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType))
|
||||
typeSec = 3600;
|
||||
else if (X_R_RequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType))
|
||||
typeSec = 86400;
|
||||
//
|
||||
return typeSec * 1000 * frequency; // ms
|
||||
} // calculateSleep
|
||||
|
||||
/**
|
||||
* Is Sleeping
|
||||
* @return sleeping
|
||||
*/
|
||||
public boolean isSleeping()
|
||||
{
|
||||
return m_sleeping;
|
||||
} // isSleeping
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer (getName())
|
||||
.append (",Prio=").append(getPriority())
|
||||
.append (",").append (getThreadGroup())
|
||||
.append (",Alive=").append(isAlive())
|
||||
.append (",Sleeping=").append(m_sleeping)
|
||||
.append (",Last=").append(getDateLastRun());
|
||||
if (m_sleeping)
|
||||
sb.append (",Next=").append(getDateNextRun(false));
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
/**
|
||||
* Get Seconds Alive
|
||||
* @return seconds alive
|
||||
*/
|
||||
public int getSecondsAlive()
|
||||
{
|
||||
if (m_start == 0)
|
||||
return 0;
|
||||
long now = System.currentTimeMillis();
|
||||
long ms = (now-m_start) / 1000;
|
||||
return (int)ms;
|
||||
} // getSecondsAlive
|
||||
|
||||
/**
|
||||
* Get Start Time
|
||||
* @return start time
|
||||
*/
|
||||
public Timestamp getStartTime()
|
||||
{
|
||||
if (m_start == 0)
|
||||
return null;
|
||||
return new Timestamp (m_start);
|
||||
} // getStartTime
|
||||
|
||||
/**
|
||||
* Get Processor Logs
|
||||
* @return logs
|
||||
*/
|
||||
public AdempiereProcessorLog[] getLogs()
|
||||
{
|
||||
return p_model.getLogs();
|
||||
} // getLogs
|
||||
|
||||
} // AdempiereServer
|
|
@ -0,0 +1,90 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Adempiere Server Group
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AdempiereServerGroup.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class AdempiereServerGroup extends ThreadGroup
|
||||
{
|
||||
/**
|
||||
* Get Adempiere Server Group
|
||||
* @return Server Group
|
||||
*/
|
||||
public static AdempiereServerGroup get()
|
||||
{
|
||||
if (s_group == null || s_group.isDestroyed())
|
||||
s_group = new AdempiereServerGroup();
|
||||
return s_group;
|
||||
} // get
|
||||
|
||||
/** Group */
|
||||
private static AdempiereServerGroup s_group = null;
|
||||
|
||||
/**
|
||||
* AdempiereServerGroup
|
||||
*/
|
||||
private AdempiereServerGroup ()
|
||||
{
|
||||
super ("AdempiereServers");
|
||||
setDaemon(true);
|
||||
setMaxPriority(Thread.MAX_PRIORITY);
|
||||
log.info(getName() + " - Parent=" + getParent());
|
||||
} // AdempiereServerGroup
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
/**
|
||||
* Uncaught Exception
|
||||
* @param t thread
|
||||
* @param e exception
|
||||
*/
|
||||
public void uncaughtException (Thread t, Throwable e)
|
||||
{
|
||||
log.info ("uncaughtException = " + e.toString());
|
||||
super.uncaughtException (t, e);
|
||||
} // uncaughtException
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return name
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return getName();
|
||||
} // toString
|
||||
|
||||
/**
|
||||
* Dump Info
|
||||
*/
|
||||
public void dump ()
|
||||
{
|
||||
log.fine(getName() + (isDestroyed() ? " (destroyed)" : ""));
|
||||
log.fine("- Parent=" + getParent());
|
||||
Thread[] list = new Thread[activeCount()];
|
||||
log.fine("- Count=" + enumerate(list, true));
|
||||
for (int i = 0; i < list.length; i++)
|
||||
log.fine("-- " + list[i]);
|
||||
} // dump
|
||||
|
||||
} // AdempiereServerGroup
|
|
@ -0,0 +1,532 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.ldap.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
import org.compiere.wf.*;
|
||||
|
||||
/**
|
||||
* Adempiere Server Manager
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AdempiereServerMgr.java,v 1.4 2006/10/09 00:23:26 jjanke Exp $
|
||||
*/
|
||||
public class AdempiereServerMgr
|
||||
{
|
||||
/**
|
||||
* Get Adempiere Server Manager
|
||||
* @return mgr
|
||||
*/
|
||||
public static AdempiereServerMgr get()
|
||||
{
|
||||
if (m_serverMgr == null)
|
||||
{
|
||||
// for faster subsequent calls
|
||||
m_serverMgr = new AdempiereServerMgr();
|
||||
m_serverMgr.startServers();
|
||||
m_serverMgr.log.info(m_serverMgr.toString());
|
||||
}
|
||||
return m_serverMgr;
|
||||
} // get
|
||||
|
||||
/** Singleton */
|
||||
private static AdempiereServerMgr m_serverMgr = null;
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
/**************************************************************************
|
||||
* Adempiere Server Manager
|
||||
*/
|
||||
private AdempiereServerMgr ()
|
||||
{
|
||||
super();
|
||||
startEnvironment();
|
||||
// m_serverMgr.startServers();
|
||||
} // AdempiereServerMgr
|
||||
|
||||
/** The Servers */
|
||||
private ArrayList<AdempiereServer> m_servers = new ArrayList<AdempiereServer>();
|
||||
/** Context */
|
||||
private Properties m_ctx = Env.getCtx();
|
||||
/** Start */
|
||||
private Timestamp m_start = new Timestamp(System.currentTimeMillis());
|
||||
|
||||
/**
|
||||
* Start Environment
|
||||
* @return true if started
|
||||
*/
|
||||
private boolean startEnvironment()
|
||||
{
|
||||
Adempiere.startup(false);
|
||||
log.info("");
|
||||
|
||||
// Set Session
|
||||
MSession session = MSession.get(getCtx(), true);
|
||||
session.setWebStoreSession(false);
|
||||
session.setWebSession("Server");
|
||||
session.save();
|
||||
//
|
||||
return true;
|
||||
} // startEnvironment
|
||||
|
||||
/**
|
||||
* Start Environment
|
||||
* @return true if started
|
||||
*/
|
||||
private boolean startServers()
|
||||
{
|
||||
log.info("");
|
||||
int noServers = 0;
|
||||
// Accounting
|
||||
MAcctProcessor[] acctModels = MAcctProcessor.getActive(m_ctx);
|
||||
for (int i = 0; i < acctModels.length; i++)
|
||||
{
|
||||
MAcctProcessor pModel = acctModels[i];
|
||||
AdempiereServer server = AdempiereServer.create(pModel);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
}
|
||||
// Request
|
||||
MRequestProcessor[] requestModels = MRequestProcessor.getActive(m_ctx);
|
||||
for (int i = 0; i < requestModels.length; i++)
|
||||
{
|
||||
MRequestProcessor pModel = requestModels[i];
|
||||
AdempiereServer server = AdempiereServer.create(pModel);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
}
|
||||
// Workflow
|
||||
MWorkflowProcessor[] workflowModels = MWorkflowProcessor.getActive(m_ctx);
|
||||
for (int i = 0; i < workflowModels.length; i++)
|
||||
{
|
||||
MWorkflowProcessor pModel = workflowModels[i];
|
||||
AdempiereServer server = AdempiereServer.create(pModel);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
}
|
||||
// Alert
|
||||
MAlertProcessor[] alertModels = MAlertProcessor.getActive(m_ctx);
|
||||
for (int i = 0; i < alertModels.length; i++)
|
||||
{
|
||||
MAlertProcessor pModel = alertModels[i];
|
||||
AdempiereServer server = AdempiereServer.create(pModel);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
}
|
||||
// Scheduler
|
||||
MScheduler[] schedulerModels = MScheduler.getActive(m_ctx);
|
||||
for (int i = 0; i < schedulerModels.length; i++)
|
||||
{
|
||||
MScheduler pModel = schedulerModels[i];
|
||||
AdempiereServer server = AdempiereServer.create(pModel);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
}
|
||||
// LDAP
|
||||
LdapProcessorModel lp = new LdapProcessorModel(m_ctx);
|
||||
AdempiereServer server = AdempiereServer.create(lp);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
m_servers.add(server);
|
||||
|
||||
|
||||
log.fine("#" + noServers);
|
||||
return startAll();
|
||||
} // startEnvironment
|
||||
|
||||
/**
|
||||
* Get Server Context
|
||||
* @return ctx
|
||||
*/
|
||||
public Properties getCtx()
|
||||
{
|
||||
return m_ctx;
|
||||
} // getCtx
|
||||
|
||||
/**
|
||||
* Start all servers
|
||||
* @return true if started
|
||||
*/
|
||||
public boolean startAll()
|
||||
{
|
||||
log.info ("");
|
||||
AdempiereServer[] servers = getInActive();
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
try
|
||||
{
|
||||
if (server.isAlive())
|
||||
continue;
|
||||
// Wait until dead
|
||||
if (server.isInterrupted())
|
||||
{
|
||||
int maxWait = 10; // 10 iterations = 1 sec
|
||||
while (server.isAlive())
|
||||
{
|
||||
if (maxWait-- == 0)
|
||||
{
|
||||
log.severe ("Wait timeout for interruped " + server);
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
Thread.sleep(100); // 1/10 sec
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "While sleeping", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do start
|
||||
if (!server.isAlive())
|
||||
{
|
||||
// replace
|
||||
server = AdempiereServer.create (server.getModel());
|
||||
if (server == null)
|
||||
m_servers.remove(i);
|
||||
else
|
||||
m_servers.set(i, server);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "Server: " + server, e);
|
||||
}
|
||||
} // for all servers
|
||||
|
||||
// Final Check
|
||||
int noRunning = 0;
|
||||
int noStopped = 0;
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
try
|
||||
{
|
||||
if (server.isAlive())
|
||||
{
|
||||
log.info("Alive: " + server);
|
||||
noRunning++;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warning("Dead: " + server);
|
||||
noStopped++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(checking) - " + server, e);
|
||||
noStopped++;
|
||||
}
|
||||
}
|
||||
log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
|
||||
AdempiereServerGroup.get().dump();
|
||||
return noStopped == 0;
|
||||
} // startAll
|
||||
|
||||
/**
|
||||
* Start Server if not started yet
|
||||
* @param serverID server ID
|
||||
* @return true if started
|
||||
*/
|
||||
public boolean start (String serverID)
|
||||
{
|
||||
AdempiereServer server = getServer(serverID);
|
||||
if (server == null)
|
||||
return false;
|
||||
if (server.isAlive())
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
// replace
|
||||
int index = m_servers.indexOf(server);
|
||||
server = AdempiereServer.create (server.getModel());
|
||||
if (server == null)
|
||||
m_servers.remove(index);
|
||||
else
|
||||
m_servers.set(index, server);
|
||||
server.start();
|
||||
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||
Thread.yield();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "Server=" + serverID, e);
|
||||
return false;
|
||||
}
|
||||
log.info(server.toString());
|
||||
AdempiereServerGroup.get().dump();
|
||||
if (server == null)
|
||||
return false;
|
||||
return server.isAlive();
|
||||
} // startIt
|
||||
|
||||
/**
|
||||
* Stop all Servers
|
||||
* @return true if stopped
|
||||
*/
|
||||
public boolean stopAll()
|
||||
{
|
||||
log.info ("");
|
||||
AdempiereServer[] servers = getActive();
|
||||
// Interrupt
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
try
|
||||
{
|
||||
if (server.isAlive() && !server.isInterrupted())
|
||||
{
|
||||
server.setPriority(Thread.MAX_PRIORITY-1);
|
||||
server.interrupt();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(interrupting) - " + server, e);
|
||||
}
|
||||
} // for all servers
|
||||
Thread.yield();
|
||||
|
||||
// Wait for death
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
try
|
||||
{
|
||||
int maxWait = 10; // 10 iterations = 1 sec
|
||||
while (server.isAlive())
|
||||
{
|
||||
if (maxWait-- == 0)
|
||||
{
|
||||
log.severe ("Wait timeout for interruped " + server);
|
||||
break;
|
||||
}
|
||||
Thread.sleep(100); // 1/10
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(waiting) - " + server, e);
|
||||
}
|
||||
} // for all servers
|
||||
|
||||
// Final Check
|
||||
int noRunning = 0;
|
||||
int noStopped = 0;
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
try
|
||||
{
|
||||
if (server.isAlive())
|
||||
{
|
||||
log.warning ("Alive: " + server);
|
||||
noRunning++;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info ("Stopped: " + server);
|
||||
noStopped++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(checking) - " + server, e);
|
||||
noRunning++;
|
||||
}
|
||||
}
|
||||
log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
|
||||
AdempiereServerGroup.get().dump();
|
||||
return noRunning == 0;
|
||||
} // stopAll
|
||||
|
||||
/**
|
||||
* Stop Server if not stopped
|
||||
* @param serverID server ID
|
||||
* @return true if interrupted
|
||||
*/
|
||||
public boolean stop (String serverID)
|
||||
{
|
||||
AdempiereServer server = getServer(serverID);
|
||||
if (server == null)
|
||||
return false;
|
||||
if (!server.isAlive())
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
server.interrupt();
|
||||
Thread.sleep(10); // 1/100 sec
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "stop", e);
|
||||
return false;
|
||||
}
|
||||
log.info(server.toString());
|
||||
AdempiereServerGroup.get().dump();
|
||||
return !server.isAlive();
|
||||
} // stop
|
||||
|
||||
|
||||
/**
|
||||
* Destroy
|
||||
*/
|
||||
public void destroy ()
|
||||
{
|
||||
log.info ("");
|
||||
stopAll();
|
||||
m_servers.clear();
|
||||
} // destroy
|
||||
|
||||
/**
|
||||
* Get Active Servers
|
||||
* @return array of active servers
|
||||
*/
|
||||
protected AdempiereServer[] getActive()
|
||||
{
|
||||
ArrayList<AdempiereServer> list = new ArrayList<AdempiereServer>();
|
||||
for (int i = 0; i < m_servers.size(); i++)
|
||||
{
|
||||
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||
if (server != null && server.isAlive() && !server.isInterrupted())
|
||||
list.add (server);
|
||||
}
|
||||
AdempiereServer[] retValue = new AdempiereServer[list.size ()];
|
||||
list.toArray (retValue);
|
||||
return retValue;
|
||||
} // getActive
|
||||
|
||||
/**
|
||||
* Get InActive Servers
|
||||
* @return array of inactive servers
|
||||
*/
|
||||
protected AdempiereServer[] getInActive()
|
||||
{
|
||||
ArrayList<AdempiereServer> list = new ArrayList<AdempiereServer>();
|
||||
for (int i = 0; i < m_servers.size(); i++)
|
||||
{
|
||||
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||
if (server != null && (!server.isAlive() || !server.isInterrupted()))
|
||||
list.add (server);
|
||||
}
|
||||
AdempiereServer[] retValue = new AdempiereServer[list.size()];
|
||||
list.toArray (retValue);
|
||||
return retValue;
|
||||
} // getInActive
|
||||
|
||||
/**
|
||||
* Get all Servers
|
||||
* @return array of servers
|
||||
*/
|
||||
public AdempiereServer[] getAll()
|
||||
{
|
||||
AdempiereServer[] retValue = new AdempiereServer[m_servers.size()];
|
||||
m_servers.toArray (retValue);
|
||||
return retValue;
|
||||
} // getAll
|
||||
|
||||
/**
|
||||
* Get Server with ID
|
||||
* @param serverID server id
|
||||
* @return server or null
|
||||
*/
|
||||
public AdempiereServer getServer (String serverID)
|
||||
{
|
||||
if (serverID == null)
|
||||
return null;
|
||||
for (int i = 0; i < m_servers.size(); i++)
|
||||
{
|
||||
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||
if (serverID.equals(server.getServerID()))
|
||||
return server;
|
||||
}
|
||||
return null;
|
||||
} // getServer
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ("AdempiereServerMgr[");
|
||||
sb.append("Servers=").append(m_servers.size())
|
||||
.append(",ContextSize=").append(m_ctx.size())
|
||||
.append(",Started=").append(m_start)
|
||||
.append ("]");
|
||||
return sb.toString ();
|
||||
} // toString
|
||||
|
||||
/**
|
||||
* Get Description
|
||||
* @return description
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return "$Revision: 1.4 $";
|
||||
} // getDescription
|
||||
|
||||
/**
|
||||
* Get Number Servers
|
||||
* @return no of servers
|
||||
*/
|
||||
public String getServerCount()
|
||||
{
|
||||
int noRunning = 0;
|
||||
int noStopped = 0;
|
||||
for (int i = 0; i < m_servers.size(); i++)
|
||||
{
|
||||
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||
if (server.isAlive())
|
||||
noRunning++;
|
||||
else
|
||||
noStopped++;
|
||||
}
|
||||
String info = String.valueOf(m_servers.size())
|
||||
+ " - Running=" + noRunning
|
||||
+ " - Stopped=" + noStopped;
|
||||
return info;
|
||||
} // getServerCount
|
||||
|
||||
/**
|
||||
* Get start date
|
||||
* @return start date
|
||||
*/
|
||||
public Timestamp getStartTime()
|
||||
{
|
||||
return m_start;
|
||||
} // getStartTime
|
||||
|
||||
} // AdempiereServerMgr
|
|
@ -0,0 +1,323 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Alert Processor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AlertProcessor.java,v 1.4 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class AlertProcessor extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* Alert Processor
|
||||
* @param model model
|
||||
*/
|
||||
public AlertProcessor (MAlertProcessor model)
|
||||
{
|
||||
super (model, 180); // 3 monute delay
|
||||
m_model = model;
|
||||
m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
|
||||
} // AlertProcessor
|
||||
|
||||
/** The Concrete Model */
|
||||
private MAlertProcessor m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Last Error Msg */
|
||||
private StringBuffer m_errors = new StringBuffer();
|
||||
/** Client onfo */
|
||||
private MClient m_client = null;
|
||||
|
||||
/**
|
||||
* Work
|
||||
*/
|
||||
protected void doWork ()
|
||||
{
|
||||
m_summary = new StringBuffer();
|
||||
m_errors = new StringBuffer();
|
||||
//
|
||||
int count = 0;
|
||||
int countError = 0;
|
||||
MAlert[] alerts = m_model.getAlerts(false);
|
||||
for (int i = 0; i < alerts.length; i++)
|
||||
{
|
||||
if (!processAlert(alerts[i]))
|
||||
countError++;
|
||||
count++;
|
||||
}
|
||||
//
|
||||
String summary = "Total=" + count;
|
||||
if (countError > 0)
|
||||
summary += ", Not processed=" + countError;
|
||||
summary += " - ";
|
||||
m_summary.insert(0, summary);
|
||||
//
|
||||
int no = m_model.deleteLog();
|
||||
m_summary.append("Logs deleted=").append(no);
|
||||
//
|
||||
MAlertProcessorLog pLog = new MAlertProcessorLog(m_model, m_summary.toString());
|
||||
pLog.setReference("#" + String.valueOf(p_runCount)
|
||||
+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
|
||||
pLog.setTextMsg(m_errors.toString());
|
||||
pLog.save();
|
||||
} // doWork
|
||||
|
||||
/**
|
||||
* Process Alert
|
||||
* @param alert alert
|
||||
* @return true if processed
|
||||
*/
|
||||
private boolean processAlert (MAlert alert)
|
||||
{
|
||||
if (!alert.isValid())
|
||||
return false;
|
||||
log.info("" + alert);
|
||||
|
||||
StringBuffer message = new StringBuffer(alert.getAlertMessage())
|
||||
.append(Env.NL);
|
||||
//
|
||||
boolean valid = true;
|
||||
boolean processed = false;
|
||||
MAlertRule[] rules = alert.getRules(false);
|
||||
for (int i = 0; i < rules.length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
message.append(Env.NL).append("================================").append(Env.NL);
|
||||
String trxName = null; // assume r/o
|
||||
|
||||
MAlertRule rule = rules[i];
|
||||
if (!rule.isValid())
|
||||
continue;
|
||||
log.fine("" + rule);
|
||||
|
||||
// Pre
|
||||
String sql = rule.getPreProcessing();
|
||||
if (sql != null && sql.length() > 0)
|
||||
{
|
||||
int no = DB.executeUpdate(sql, false, trxName);
|
||||
if (no == -1)
|
||||
{
|
||||
ValueNamePair error = CLogger.retrieveError();
|
||||
rule.setErrorMsg("Pre=" + error.getName());
|
||||
m_errors.append("Pre=" + error.getName());
|
||||
rule.setIsValid(false);
|
||||
rule.save();
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
} // Pre
|
||||
|
||||
// The processing
|
||||
sql = rule.getSql();
|
||||
if (alert.isEnforceRoleSecurity()
|
||||
|| alert.isEnforceClientSecurity())
|
||||
{
|
||||
int AD_Role_ID = alert.getFirstAD_Role_ID();
|
||||
if (AD_Role_ID == -1)
|
||||
AD_Role_ID = alert.getFirstUserAD_Role_ID();
|
||||
if (AD_Role_ID != -1)
|
||||
{
|
||||
MRole role = MRole.get(getCtx(), AD_Role_ID);
|
||||
sql = role.addAccessSQL(sql, null, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String text = listSqlSelect(sql, trxName);
|
||||
if (text != null && text.length() > 0)
|
||||
{
|
||||
message.append(text);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
rule.setErrorMsg("Select=" + e.getLocalizedMessage());
|
||||
m_errors.append("Select=" + e.getLocalizedMessage());
|
||||
rule.setIsValid(false);
|
||||
rule.save();
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Post
|
||||
sql = rule.getPostProcessing();
|
||||
if (sql != null && sql.length() > 0)
|
||||
{
|
||||
int no = DB.executeUpdate(sql, false, trxName);
|
||||
if (no == -1)
|
||||
{
|
||||
ValueNamePair error = CLogger.retrieveError();
|
||||
rule.setErrorMsg("Post=" + error.getName());
|
||||
m_errors.append("Post=" + error.getName());
|
||||
rule.setIsValid(false);
|
||||
rule.save();
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
} // Post
|
||||
|
||||
/** Trx */
|
||||
if (trxName != null)
|
||||
{
|
||||
Trx trx = Trx.get(trxName, false);
|
||||
if (trx != null)
|
||||
{
|
||||
trx.commit();
|
||||
trx.close();
|
||||
}
|
||||
}
|
||||
} // for all rules
|
||||
|
||||
// Update header if error
|
||||
if (!valid)
|
||||
{
|
||||
alert.setIsValid(false);
|
||||
alert.save();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nothing to report
|
||||
if (!processed)
|
||||
{
|
||||
m_summary.append(alert.getName()).append("=No Result - ");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send Message
|
||||
int countMail = 0;
|
||||
MAlertRecipient[] recipients = alert.getRecipients(false);
|
||||
for (int i = 0; i < recipients.length; i++)
|
||||
{
|
||||
MAlertRecipient recipient = recipients[i];
|
||||
if (recipient.getAD_User_ID() >= 0) // System == 0
|
||||
if (m_client.sendEMail(recipient.getAD_User_ID(),
|
||||
alert.getAlertSubject(), message.toString(), null))
|
||||
countMail++;
|
||||
if (recipient.getAD_Role_ID() >= 0) // SystemAdministrator == 0
|
||||
{
|
||||
MUserRoles[] urs = MUserRoles.getOfRole(getCtx(), recipient.getAD_Role_ID());
|
||||
for (int j = 0; j < urs.length; j++)
|
||||
{
|
||||
MUserRoles ur = urs[j];
|
||||
if (!ur.isActive())
|
||||
continue;
|
||||
if (m_client.sendEMail (ur.getAD_User_ID(),
|
||||
alert.getAlertSubject(), message.toString(), null))
|
||||
countMail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_summary.append(alert.getName()).append(" (EMails=").append(countMail).append(") - ");
|
||||
return valid;
|
||||
} // processAlert
|
||||
|
||||
/**
|
||||
* List Sql Select
|
||||
* @param sql sql select
|
||||
* @param trxName transaction
|
||||
* @return list of rows & values
|
||||
* @throws Exception
|
||||
*/
|
||||
private String listSqlSelect (String sql, String trxName) throws Exception
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
PreparedStatement pstmt = null;
|
||||
Exception error = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, trxName);
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
ResultSetMetaData meta = rs.getMetaData();
|
||||
while (rs.next ())
|
||||
{
|
||||
result.append("------------------").append(Env.NL);
|
||||
for (int col = 1; col <= meta.getColumnCount(); col++)
|
||||
{
|
||||
result.append(meta.getColumnLabel(col)).append(" = ");
|
||||
result.append(rs.getString(col));
|
||||
result.append(Env.NL);
|
||||
} // for all columns
|
||||
}
|
||||
if (result.length() == 0)
|
||||
log.fine("No rows selected");
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
error = e;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
// Error occured
|
||||
if (error != null)
|
||||
throw new Exception ("(" + sql + ") " + Env.NL
|
||||
+ error.getLocalizedMessage());
|
||||
|
||||
return result.toString();
|
||||
} // listSqlSelect
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString();
|
||||
} // getServerInfo
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Test
|
||||
* @param args ignored
|
||||
*/
|
||||
public static void main (String[] args)
|
||||
{
|
||||
Adempiere.startup(true);
|
||||
MAlertProcessor model = new MAlertProcessor (Env.getCtx(), 100, null);
|
||||
AlertProcessor ap = new AlertProcessor(model);
|
||||
ap.start();
|
||||
|
||||
|
||||
} // main
|
||||
|
||||
} // AlertProcessor
|
|
@ -0,0 +1,700 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import javax.mail.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Request Mail Processor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: EMailProcessor.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class EMailProcessor
|
||||
{
|
||||
/**
|
||||
* EMail Processor
|
||||
* @param client client
|
||||
*/
|
||||
public EMailProcessor (MClient client)
|
||||
{
|
||||
this (client.getSMTPHost(), client.getRequestUser(), client.getRequestUserPW());
|
||||
} // EMailProcessor
|
||||
|
||||
/**
|
||||
* EMail Processor
|
||||
* @param host host
|
||||
* @param user user id
|
||||
* @param password password
|
||||
*/
|
||||
public EMailProcessor (String host, String user, String password)
|
||||
{
|
||||
m_host = host;
|
||||
m_user = user;
|
||||
m_pass = password;
|
||||
} // EMail
|
||||
|
||||
/** EMail Host Parameter */
|
||||
private String m_host = null;
|
||||
/** EMail User Parameter */
|
||||
private String m_user = null;
|
||||
/** Password Parameter */
|
||||
private String m_pass = null;
|
||||
|
||||
/** Session */
|
||||
private Session m_session = null;
|
||||
/** Store */
|
||||
private Store m_store = null;
|
||||
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
/** Process Error */
|
||||
private static final int ERROR = 0;
|
||||
/** Process Request */
|
||||
private static final int REQUEST = 1;
|
||||
/** Process Workflow */
|
||||
private static final int WORKFLOW = 2;
|
||||
|
||||
/** Process Delivery Confirm */
|
||||
private static final int DELIVERY = 9;
|
||||
|
||||
/**
|
||||
* Process Messages in InBox
|
||||
* @return number of mails processed
|
||||
*/
|
||||
public int processMessages()
|
||||
{
|
||||
int processed = 0;
|
||||
try
|
||||
{
|
||||
getSession();
|
||||
getStore();
|
||||
processed = processInBox();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "processInBox", e);
|
||||
}
|
||||
// Cleanup
|
||||
try
|
||||
{
|
||||
if (m_store.isConnected())
|
||||
m_store.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
m_store = null;
|
||||
return processed;
|
||||
} // processMessages
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Get Session
|
||||
* @return Session
|
||||
* @throws Exception
|
||||
*/
|
||||
private Session getSession() throws Exception
|
||||
{
|
||||
if (m_session != null)
|
||||
return m_session;
|
||||
|
||||
// Session
|
||||
Properties props = System.getProperties();
|
||||
props.put("mail.store.protocol", "smtp");
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.host", m_host);
|
||||
props.put("mail.smtp.auth","true");
|
||||
EMailAuthenticator auth = new EMailAuthenticator (m_user, m_pass);
|
||||
//
|
||||
m_session = Session.getDefaultInstance(props, auth);
|
||||
m_session.setDebug(CLogMgt.isLevelFinest());
|
||||
log.fine("getSession - " + m_session);
|
||||
return m_session;
|
||||
} // getSession
|
||||
|
||||
|
||||
/**
|
||||
* Get Store
|
||||
* @return Store
|
||||
* @throws Exception
|
||||
*/
|
||||
private Store getStore() throws Exception
|
||||
{
|
||||
if (m_store != null)
|
||||
return m_store;
|
||||
if (getSession() == null)
|
||||
throw new IllegalStateException("No Session");
|
||||
|
||||
// Get IMAP Store
|
||||
m_store = m_session.getStore("imap");
|
||||
// Connect
|
||||
m_store.connect();
|
||||
//
|
||||
log.fine("getStore - " + m_store);
|
||||
return m_store;
|
||||
} // getStore
|
||||
|
||||
|
||||
/**
|
||||
* Process InBox
|
||||
* @return number of processed
|
||||
* @throws Exception
|
||||
*/
|
||||
private int processInBox() throws Exception
|
||||
{
|
||||
// Folder
|
||||
Folder folder;
|
||||
folder = m_store.getDefaultFolder();
|
||||
if (folder == null)
|
||||
throw new IllegalStateException("No default folder");
|
||||
// Open Inbox
|
||||
Folder inbox = folder.getFolder("INBOX");
|
||||
if (!inbox.exists())
|
||||
throw new IllegalStateException("No Inbox");
|
||||
inbox.open(Folder.READ_WRITE);
|
||||
log.fine("processInBox - " + inbox.getName()
|
||||
+ "; Messages Total=" + inbox.getMessageCount()
|
||||
+ "; New=" + inbox.getNewMessageCount());
|
||||
|
||||
// Open Request
|
||||
Folder requestFolder = folder.getFolder("CRequest");
|
||||
if (!requestFolder.exists() && !requestFolder.create(Folder.HOLDS_MESSAGES))
|
||||
throw new IllegalStateException("Cannot create Request Folder");
|
||||
requestFolder.open(Folder.READ_WRITE);
|
||||
|
||||
// Open Workflow
|
||||
Folder workflowFolder = folder.getFolder("CWorkflow");
|
||||
if (!workflowFolder.exists() && !workflowFolder.create(Folder.HOLDS_MESSAGES))
|
||||
throw new IllegalStateException("Cannot create Workflow Folder");
|
||||
workflowFolder.open(Folder.READ_WRITE);
|
||||
|
||||
// Open Error
|
||||
Folder errorFolder = folder.getFolder("AdempiereError");
|
||||
if (!errorFolder.exists() && !errorFolder.create(Folder.HOLDS_MESSAGES))
|
||||
throw new IllegalStateException("Cannot create Error Folder");
|
||||
errorFolder.open(Folder.READ_WRITE);
|
||||
|
||||
// Messages
|
||||
Message[] messages = inbox.getMessages();
|
||||
/**
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
fp.add(FetchProfile.Item.FLAGS);
|
||||
fp.add("X-Mailer");
|
||||
inbox.fetch(messages, fp);
|
||||
**/
|
||||
//
|
||||
int noProcessed = 0;
|
||||
int noError = 0;
|
||||
for (int i = 0; i < messages.length; i++)
|
||||
// for (int i = messages.length-1; i >= 0; i--) // newest first
|
||||
{
|
||||
Message msg = messages[i];
|
||||
int result = processMessage (msg);
|
||||
if (result == REQUEST)
|
||||
{
|
||||
msg.setFlag(Flags.Flag.SEEN, true);
|
||||
msg.setFlag(Flags.Flag.ANSWERED, true);
|
||||
// Copy to processed
|
||||
requestFolder.appendMessages(new Message[]{msg});
|
||||
}
|
||||
else if (result == WORKFLOW)
|
||||
{
|
||||
msg.setFlag(Flags.Flag.SEEN, true);
|
||||
msg.setFlag(Flags.Flag.ANSWERED, true);
|
||||
// Copy to processed
|
||||
workflowFolder.appendMessages(new Message[]{msg});
|
||||
}
|
||||
else if (result == DELIVERY)
|
||||
{
|
||||
msg.setFlag(Flags.Flag.SEEN, true);
|
||||
msg.setFlag(Flags.Flag.ANSWERED, true);
|
||||
}
|
||||
else // error
|
||||
{
|
||||
errorFolder.appendMessages(new Message[]{msg});
|
||||
noError++;
|
||||
}
|
||||
// Delete in InBox
|
||||
// msg.setFlag(Flags.Flag.DELETED, true);
|
||||
// Message[] deleted = inbox.expunge();
|
||||
//
|
||||
noProcessed++;
|
||||
}
|
||||
|
||||
log.info("processInBox - Total=" + noProcessed + " - Errors=" + noError);
|
||||
// Fini
|
||||
errorFolder.close(false);
|
||||
requestFolder.close(false);
|
||||
workflowFolder.close(false);
|
||||
//
|
||||
inbox.close(true);
|
||||
return noProcessed;
|
||||
} // processInBox
|
||||
|
||||
|
||||
/**
|
||||
* Process Message
|
||||
* @param msg message
|
||||
* @return Type of Message
|
||||
* @throws Exception
|
||||
*/
|
||||
private int processMessage (Message msg) throws Exception
|
||||
{
|
||||
dumpEnvelope (msg);
|
||||
dumpBody (msg);
|
||||
printOut (":::::::::::::::");
|
||||
printOut (getSubject(msg));
|
||||
printOut (":::::::::::::::");
|
||||
printOut (getMessage(msg));
|
||||
printOut (":::::::::::::::");
|
||||
String delivery = getDeliveryReport(msg);
|
||||
printOut (delivery);
|
||||
printOut (":::::::::::::::");
|
||||
|
||||
// if (delivery != null)
|
||||
// return DELIVERY;
|
||||
|
||||
// Unknown
|
||||
return ERROR;
|
||||
} // processMessage
|
||||
|
||||
/**
|
||||
* Get Subject
|
||||
* @param msg message
|
||||
* @return subject or ""
|
||||
*/
|
||||
private String getSubject (Message msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
String str = msg.getSubject();
|
||||
if (str != null)
|
||||
return str.trim();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "getSubject", e);
|
||||
}
|
||||
return "";
|
||||
} // getSubject
|
||||
|
||||
/**
|
||||
* Get Message
|
||||
* @param msg Message
|
||||
* @return message or ""
|
||||
*/
|
||||
private String getMessage (Part msg)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try
|
||||
{
|
||||
// Text
|
||||
if (msg.isMimeType("text/plain"))
|
||||
{
|
||||
sb.append(msg.getContent());
|
||||
}
|
||||
// Other Text (e.g. html/xml)
|
||||
else if (msg.isMimeType("text/*"))
|
||||
{
|
||||
sb.append(msg.getContent());
|
||||
}
|
||||
// Nested
|
||||
else if (msg.isMimeType("message/rfc822"))
|
||||
{
|
||||
sb.append(msg.getContent());
|
||||
}
|
||||
// Multi Part Alternative
|
||||
else if (msg.isMimeType("multipart/alternative"))
|
||||
{
|
||||
String plainText = null;
|
||||
String otherStuff = null;
|
||||
//
|
||||
Multipart mp = (Multipart)msg.getContent();
|
||||
int count = mp.getCount();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Part part = mp.getBodyPart(i);
|
||||
Object content = part.getContent();
|
||||
if (content == null || content.toString().trim().length() == 0)
|
||||
continue;
|
||||
if (part.isMimeType("text/plain"))
|
||||
plainText = content.toString();
|
||||
else
|
||||
otherStuff = content.toString();
|
||||
}
|
||||
if (plainText != null)
|
||||
sb.append(plainText);
|
||||
else if (otherStuff != null)
|
||||
sb.append(otherStuff);
|
||||
}
|
||||
// Multi Part
|
||||
else if (msg.isMimeType("multipart/*"))
|
||||
{
|
||||
Multipart mp = (Multipart)msg.getContent();
|
||||
int count = mp.getCount();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
String str = getMessage(mp.getBodyPart(i));
|
||||
if (str.length() > 0)
|
||||
{
|
||||
if (sb.length() > 0)
|
||||
sb.append("\n-----\n");
|
||||
sb.append(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If we actually want to see the data, and it's not a
|
||||
* MIME type we know, fetch it and check its Java type.
|
||||
*/
|
||||
Object o = msg.getContent();
|
||||
if (o instanceof String)
|
||||
{
|
||||
sb.append(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "getMessage", e);
|
||||
}
|
||||
return sb.toString().trim();
|
||||
} // getMessage
|
||||
|
||||
/**
|
||||
* Get Delivery Report
|
||||
* @param msg message
|
||||
* @return delivery info or null
|
||||
*/
|
||||
private String getDeliveryReport (Part msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (msg.isMimeType("multipart/report"))
|
||||
{
|
||||
String deliveryMessage = null;
|
||||
String otherStuff = null;
|
||||
//
|
||||
Multipart mp = (Multipart)msg.getContent();
|
||||
int count = mp.getCount();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Part part = mp.getBodyPart(i);
|
||||
Object content = part.getContent();
|
||||
if (content == null)
|
||||
continue;
|
||||
if (part.isMimeType("message/*"))
|
||||
deliveryMessage = getDeliveredReportDetail (part);
|
||||
else
|
||||
otherStuff = content.toString().trim();
|
||||
}
|
||||
if (deliveryMessage != null)
|
||||
return deliveryMessage;
|
||||
return otherStuff;
|
||||
}
|
||||
else if (msg.isMimeType("message/*"))
|
||||
{
|
||||
return getDeliveredReportDetail (msg);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "getDeliveryReport", e);
|
||||
}
|
||||
// Nothing
|
||||
return null;
|
||||
} // getDeliveryReport
|
||||
|
||||
/**
|
||||
* Get Delivered Report Detail
|
||||
* @param part Mime Type message/*
|
||||
* @return info or null
|
||||
* @throws Exception
|
||||
*/
|
||||
private String getDeliveredReportDetail (Part part) throws Exception
|
||||
{
|
||||
Object content = part.getContent();
|
||||
if (content == null)
|
||||
return null;
|
||||
|
||||
String deliveryMessage = null;
|
||||
if (content instanceof InputStream)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
InputStream is = (InputStream)content;
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
sb.append((char)c);
|
||||
deliveryMessage = sb.toString().trim();
|
||||
}
|
||||
else
|
||||
deliveryMessage = content.toString().trim();
|
||||
//
|
||||
if (deliveryMessage == null)
|
||||
return null;
|
||||
|
||||
// Final-Recipient: RFC822; jjanke@adempiere.org
|
||||
int index = deliveryMessage.indexOf("Final-Recipient:");
|
||||
if (index != -1)
|
||||
{
|
||||
String finalRecipient = deliveryMessage.substring(index);
|
||||
int atIndex = finalRecipient.indexOf("@");
|
||||
if (atIndex != -1)
|
||||
{
|
||||
index = finalRecipient.lastIndexOf(' ', atIndex);
|
||||
if (index != -1)
|
||||
finalRecipient = finalRecipient.substring(index+1);
|
||||
atIndex = finalRecipient.indexOf("@");
|
||||
if (atIndex != -1)
|
||||
index = finalRecipient.indexOf(' ', atIndex);
|
||||
if (index != -1)
|
||||
finalRecipient = finalRecipient.substring(0, index);
|
||||
index = finalRecipient.indexOf('\n');
|
||||
if (index != -1)
|
||||
finalRecipient = finalRecipient.substring(0, index);
|
||||
return finalRecipient.trim();
|
||||
}
|
||||
}
|
||||
return deliveryMessage;
|
||||
} // getDeliveredReportDetail
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Print Envelope
|
||||
* @param m message
|
||||
* @throws Exception
|
||||
*/
|
||||
private void dumpEnvelope(Message m) throws Exception
|
||||
{
|
||||
printOut("-----------------------------------------------------------------");
|
||||
Address[] a;
|
||||
// FROM
|
||||
if ((a = m.getFrom()) != null)
|
||||
{
|
||||
for (int j = 0; j < a.length; j++)
|
||||
printOut("FROM: " + a[j].toString());
|
||||
}
|
||||
|
||||
// TO
|
||||
if ((a = m.getRecipients(Message.RecipientType.TO)) != null)
|
||||
{
|
||||
for (int j = 0; j < a.length; j++)
|
||||
printOut("TO: " + a[j].toString());
|
||||
}
|
||||
|
||||
// SUBJECT
|
||||
printOut("SUBJECT: " + m.getSubject());
|
||||
|
||||
// DATE
|
||||
java.util.Date d = m.getSentDate();
|
||||
printOut("SendDate: " + (d != null ? d.toString() : "UNKNOWN"));
|
||||
|
||||
// FLAGS
|
||||
Flags flags = m.getFlags();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
|
||||
|
||||
boolean first = true;
|
||||
for (int i = 0; i < sf.length; i++)
|
||||
{
|
||||
String s;
|
||||
Flags.Flag f = sf[i];
|
||||
if (f == Flags.Flag.ANSWERED)
|
||||
s = "\\Answered";
|
||||
else if (f == Flags.Flag.DELETED)
|
||||
s = "\\Deleted";
|
||||
else if (f == Flags.Flag.DRAFT)
|
||||
s = "\\Draft";
|
||||
else if (f == Flags.Flag.FLAGGED)
|
||||
s = "\\Flagged";
|
||||
else if (f == Flags.Flag.RECENT)
|
||||
s = "\\Recent";
|
||||
else if (f == Flags.Flag.SEEN)
|
||||
s = "\\Seen";
|
||||
else
|
||||
continue; // skip it
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(' ');
|
||||
sb.append(s);
|
||||
}
|
||||
|
||||
String[] uf = flags.getUserFlags(); // get the user flag strings
|
||||
for (int i = 0; i < uf.length; i++)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(' ');
|
||||
sb.append(uf[i]);
|
||||
}
|
||||
printOut("FLAGS: " + sb.toString());
|
||||
|
||||
// X-MAILER
|
||||
String[] hdrs = m.getHeader("X-Mailer");
|
||||
if (hdrs != null)
|
||||
{
|
||||
StringBuffer sb1 = new StringBuffer("X-Mailer: ");
|
||||
for (int i = 0; i < hdrs.length; i++)
|
||||
sb1.append(hdrs[i]).append(" ");
|
||||
printOut(sb1.toString());
|
||||
}
|
||||
else
|
||||
printOut("X-Mailer NOT available");
|
||||
|
||||
// Message ID
|
||||
hdrs = m.getHeader("Message-ID");
|
||||
if (hdrs != null)
|
||||
{
|
||||
StringBuffer sb1 = new StringBuffer("Message-ID: ");
|
||||
for (int i = 0; i < hdrs.length; i++)
|
||||
sb1.append(hdrs[i]).append(" ");
|
||||
printOut(sb1.toString());
|
||||
}
|
||||
else
|
||||
printOut("Message-ID NOT available");
|
||||
|
||||
// All
|
||||
printOut("ALL HEADERs:");
|
||||
Enumeration en = m.getAllHeaders();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
Header hdr = (Header)en.nextElement();
|
||||
printOut (" " + hdr.getName() + " = " + hdr.getValue());
|
||||
}
|
||||
|
||||
|
||||
printOut("-----------------------------------------------------------------");
|
||||
} // printEnvelope
|
||||
|
||||
/**
|
||||
* Print Body
|
||||
* @param p
|
||||
* @throws Exception
|
||||
*/
|
||||
private void dumpBody (Part p) throws Exception
|
||||
{
|
||||
// http://www.iana.org/assignments/media-types/
|
||||
printOut("=================================================================");
|
||||
printOut("CONTENT-TYPE: " + p.getContentType());
|
||||
/**
|
||||
Enumeration en = p.getAllHeaders();
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
Header hdr = (Header)en.nextElement();
|
||||
printOut (" " + hdr.getName() + " = " + hdr.getValue());
|
||||
}
|
||||
printOut("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
|
||||
/** **/
|
||||
|
||||
/**
|
||||
* Using isMimeType to determine the content type avoids
|
||||
* fetching the actual content data until we need it.
|
||||
*/
|
||||
if (p.isMimeType("text/plain"))
|
||||
{
|
||||
printOut("Plain text ---------------------------");
|
||||
System.out.println((String)p.getContent());
|
||||
}
|
||||
else if (p.getContentType().toUpperCase().startsWith("TEXT"))
|
||||
{
|
||||
printOut("Other text ---------------------------");
|
||||
System.out.println((String)p.getContent());
|
||||
}
|
||||
else if (p.isMimeType("multipart/*"))
|
||||
{
|
||||
printOut("Multipart ---------------------------");
|
||||
Multipart mp = (Multipart)p.getContent();
|
||||
int count = mp.getCount();
|
||||
for (int i = 0; i < count; i++)
|
||||
dumpBody(mp.getBodyPart(i));
|
||||
}
|
||||
else if (p.isMimeType("message/rfc822"))
|
||||
{
|
||||
printOut("Nested ---------------------------");
|
||||
dumpBody((Part)p.getContent());
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If we actually want to see the data, and it's not a
|
||||
* MIME type we know, fetch it and check its Java type.
|
||||
*/
|
||||
Object o = p.getContent();
|
||||
if (o instanceof String)
|
||||
{
|
||||
printOut("This is a string ---------------------------");
|
||||
System.out.println((String)o);
|
||||
}
|
||||
else if (o instanceof InputStream)
|
||||
{
|
||||
printOut("This is just an input stream ---------------------------");
|
||||
InputStream is = (InputStream)o;
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
System.out.write(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
printOut("This is an unknown type ---------------------------");
|
||||
printOut(o.toString());
|
||||
}
|
||||
}
|
||||
printOut("=================================================================");
|
||||
} // printBody
|
||||
|
||||
/**
|
||||
* Print
|
||||
* @param s string
|
||||
*/
|
||||
private static void printOut(String s)
|
||||
{
|
||||
// System.out.print(indentStr.substring(0, level * 2));
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Main Test
|
||||
* @param args ignored
|
||||
*/
|
||||
public static void main (String[] args)
|
||||
{
|
||||
Adempiere.startupEnvironment(true);
|
||||
EMailProcessor m = new EMailProcessor("admin", "test", "testadempiere");
|
||||
m.processMessages();
|
||||
|
||||
// System.out.println(EMailServer.send("main", "jjanke@adempiere.org", "jjanke@yahoo.com", "test1", "test1 message"));
|
||||
// System.out.println(EMailServer.send("main", "administrator@adempiere.org", "jjanke@yahoo.com", "test2", "test2 message"));
|
||||
// System.out.println(EMailServer.send("main", "jjanke@adempiere.org", "jjanke@yahoo.com", "test3", "test3 message"));
|
||||
|
||||
} // main
|
||||
|
||||
} // EMailProcessor
|
|
@ -0,0 +1,655 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Request Processor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: RequestProcessor.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class RequestProcessor extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* RequestProcessor
|
||||
* @param model model
|
||||
*/
|
||||
public RequestProcessor (MRequestProcessor model)
|
||||
{
|
||||
super (model, 60); // 1 minute delay
|
||||
m_model = model;
|
||||
m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
|
||||
} // RequestProcessor
|
||||
|
||||
/** The Concrete Model */
|
||||
private MRequestProcessor m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Client onfo */
|
||||
private MClient m_client = null;
|
||||
|
||||
/**************************************************************************
|
||||
* Do the actual Work
|
||||
*/
|
||||
protected void doWork()
|
||||
{
|
||||
m_summary = new StringBuffer();
|
||||
//
|
||||
processEMail();
|
||||
findSalesRep ();
|
||||
processRequests ();
|
||||
processStatus();
|
||||
processECR();
|
||||
//
|
||||
int no = m_model.deleteLog();
|
||||
m_summary.append("Logs deleted=").append(no);
|
||||
//
|
||||
MRequestProcessorLog pLog = new MRequestProcessorLog(m_model, m_summary.toString());
|
||||
pLog.setReference("#" + String.valueOf(p_runCount)
|
||||
+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
|
||||
pLog.save();
|
||||
} // doWork
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Process requests.
|
||||
* Scheduled - are they due?
|
||||
*/
|
||||
private void processRequests ()
|
||||
{
|
||||
/**
|
||||
* Due Requests
|
||||
*/
|
||||
String sql = "SELECT * FROM R_Request "
|
||||
+ "WHERE DueType='" + MRequest.DUETYPE_Scheduled + "' AND Processed='N'"
|
||||
+ " AND DateNextAction > SysDate"
|
||||
+ " AND AD_Client_ID=?";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND R_RequestType_ID=?";
|
||||
PreparedStatement pstmt = null;
|
||||
int count = 0;
|
||||
int countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MRequest request = new MRequest (getCtx(), rs, null);
|
||||
request.setDueType();
|
||||
if (request.isDue())
|
||||
{
|
||||
if (request.getRequestType().isEMailWhenDue())
|
||||
{
|
||||
if (sendEmail (request, "RequestDue"))
|
||||
{
|
||||
request.setDateLastAlert();
|
||||
countEMails++;
|
||||
}
|
||||
}
|
||||
request.save();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("New Due #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
|
||||
/**
|
||||
* Overdue Requests.
|
||||
* Due Requests - are they overdue?
|
||||
*/
|
||||
sql = "SELECT * FROM R_Request r "
|
||||
+ "WHERE r.DueType='" + MRequest.DUETYPE_Due + "' AND r.Processed='N'"
|
||||
+ " AND AD_Client_ID=?"
|
||||
+ " AND EXISTS (SELECT * FROM R_RequestType rt "
|
||||
+ "WHERE r.R_RequestType_ID=rt.R_RequestType_ID"
|
||||
+ " AND (r.DateNextAction+rt.DueDateTolerance) > SysDate)";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND r.R_RequestType_ID=?";
|
||||
count = 0;
|
||||
countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MRequest request = new MRequest (getCtx(), rs, null);
|
||||
request.setDueType();
|
||||
if (request.isOverdue())
|
||||
{
|
||||
if (request.getRequestType().isEMailWhenOverdue()
|
||||
&& !TimeUtil.isSameDay(request.getDateLastAlert(), null))
|
||||
{
|
||||
if (sendEmail (request, "RequestDue"))
|
||||
{
|
||||
request.setDateLastAlert();
|
||||
countEMails++;
|
||||
}
|
||||
}
|
||||
request.save();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("New Overdue #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
|
||||
/**
|
||||
* Send (over)due alerts
|
||||
*/
|
||||
if (m_model.getOverdueAlertDays() > 0)
|
||||
{
|
||||
sql = "SELECT * FROM R_Request "
|
||||
+ "WHERE Processed='N'"
|
||||
+ " AND AD_Client_ID=?"
|
||||
+ " AND (DateNextAction+" + m_model.getOverdueAlertDays() + ") > SysDate"
|
||||
+ " AND (DateLastAlert IS NULL";
|
||||
if (m_model.getRemindDays() > 0)
|
||||
sql += " OR (DateLastAlert+" + m_model.getRemindDays()
|
||||
+ ") > SysDate";
|
||||
sql += ")";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND R_RequestType_ID=?";
|
||||
count = 0;
|
||||
countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MRequest request = new MRequest (getCtx(), rs, null);
|
||||
request.setDueType();
|
||||
if (request.getRequestType().isEMailWhenOverdue()
|
||||
&& (request.getDateLastAlert() == null
|
||||
|| !TimeUtil.isSameDay(request.getDateLastAlert(), null)))
|
||||
{
|
||||
if (sendEmail (request, "RequestAlert"))
|
||||
{
|
||||
request.setDateLastAlert();
|
||||
countEMails++;
|
||||
}
|
||||
}
|
||||
request.save();
|
||||
count++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("Alerts #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
} // Overdue
|
||||
|
||||
/**
|
||||
* Escalate
|
||||
*/
|
||||
if (m_model.getOverdueAssignDays() > 0)
|
||||
{
|
||||
sql = "SELECT * FROM R_Request "
|
||||
+ "WHERE Processed='N'"
|
||||
+ " AND AD_Client_ID=?"
|
||||
+ " AND IsEscalated='N'"
|
||||
+ " AND (DateNextAction+" + m_model.getOverdueAssignDays()
|
||||
+ ") > SysDate";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND R_RequestType_ID=?";
|
||||
count = 0;
|
||||
countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MRequest request = new MRequest (getCtx(), rs, null);
|
||||
if (escalate(request))
|
||||
count++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("Escalated #").append(count).append(" - ");
|
||||
} // Esacalate
|
||||
|
||||
/**
|
||||
* Send inactivity alerts
|
||||
*/
|
||||
if (m_model.getInactivityAlertDays() > 0)
|
||||
{
|
||||
sql = "SELECT * FROM R_Request "
|
||||
+ "WHERE Processed='N'"
|
||||
+ " AND AD_Client_ID=?"
|
||||
+ " AND (Updated+" + m_model.getInactivityAlertDays() + ") > SysDate"
|
||||
+ " AND (DateLastAlert IS NULL";
|
||||
if (m_model.getRemindDays() > 0)
|
||||
sql += " OR (DateLastAlert+" + m_model.getRemindDays()
|
||||
+ ") < SysDate";
|
||||
sql += ")";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND R_RequestType_ID=?";
|
||||
count = 0;
|
||||
countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MRequest request = new MRequest (getCtx(), rs, null);
|
||||
request.setDueType();
|
||||
if (request.getDateLastAlert() == null
|
||||
|| !TimeUtil.isSameDay(request.getDateLastAlert(), null))
|
||||
{
|
||||
if (sendEmail (request, "RequestInactive"))
|
||||
{
|
||||
request.setDateLastAlert();
|
||||
countEMails++;
|
||||
}
|
||||
request.save();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("Inactivity #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
} // Inactivity
|
||||
|
||||
//
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
} // processRequests
|
||||
|
||||
/**
|
||||
* Send Alert EMail
|
||||
* @param request request
|
||||
* @param AD_Message message
|
||||
* @return true if sent
|
||||
*/
|
||||
private boolean sendEmail (MRequest request, String AD_Message)
|
||||
{
|
||||
// Alert: Request {0} overdue
|
||||
String subject = Msg.getMsg(m_client.getAD_Language(), AD_Message,
|
||||
new String[] {request.getDocumentNo()});
|
||||
return m_client.sendEMail(request.getSalesRep_ID(),
|
||||
subject, request.getSummary(), request.createPDF());
|
||||
} // sendAlert
|
||||
|
||||
/**
|
||||
* Escalate
|
||||
* @param request request
|
||||
* @return true if saved
|
||||
*/
|
||||
private boolean escalate (MRequest request)
|
||||
{
|
||||
// Get Supervisor
|
||||
MUser supervisor = request.getSalesRep(); // self
|
||||
int supervisor_ID = request.getSalesRep().getSupervisor_ID();
|
||||
if (supervisor_ID == 0 && m_model.getSupervisor_ID() != 0)
|
||||
supervisor_ID = m_model.getSupervisor_ID();
|
||||
if (supervisor_ID != 0 && supervisor_ID != request.getAD_User_ID())
|
||||
supervisor = MUser.get(getCtx(), supervisor_ID);
|
||||
|
||||
// Escalated: Request {0} to {1}
|
||||
String subject = Msg.getMsg(m_client.getAD_Language(), "RequestEscalate",
|
||||
new String[] {request.getDocumentNo(), supervisor.getName()});
|
||||
String to = request.getSalesRep().getEMail();
|
||||
if (to == null || to.length() == 0)
|
||||
log.warning("SalesRep has no EMail - " + request.getSalesRep());
|
||||
else
|
||||
m_client.sendEMail(request.getSalesRep_ID(),
|
||||
subject, request.getSummary(), request.createPDF());
|
||||
|
||||
// Not the same - send mail to supervisor
|
||||
if (request.getSalesRep_ID() != supervisor.getAD_User_ID())
|
||||
{
|
||||
to = supervisor.getEMail();
|
||||
if (to == null || to.length() == 0)
|
||||
log.warning("Supervisor has no EMail - " + supervisor);
|
||||
else
|
||||
m_client.sendEMail(supervisor.getAD_User_ID(),
|
||||
subject, request.getSummary(), request.createPDF());
|
||||
}
|
||||
|
||||
// ----------------
|
||||
request.setDueType();
|
||||
request.setIsEscalated(true);
|
||||
request.setResult(subject);
|
||||
return request.save();
|
||||
} // escalate
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Process Request Status
|
||||
*/
|
||||
private void processStatus()
|
||||
{
|
||||
int count = 0;
|
||||
// Requests with status with after timeout
|
||||
String sql = "SELECT * FROM R_Request r WHERE EXISTS ("
|
||||
+ "SELECT * FROM R_Status s "
|
||||
+ "WHERE r.R_Status_ID=s.R_Status_ID"
|
||||
+ " AND s.TimeoutDays > 0 AND s.Next_Status_ID > 0"
|
||||
+ " AND r.Updated+s.TimeoutDays < SysDate"
|
||||
+ ") "
|
||||
+ "ORDER BY R_Status_ID";
|
||||
PreparedStatement pstmt = null;
|
||||
MStatus status = null;
|
||||
MStatus next = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MRequest r = new MRequest(getCtx(), rs, null);
|
||||
// Get/Check Status
|
||||
if (status == null || status.getR_Status_ID() != r.getR_Status_ID())
|
||||
status = MStatus.get(getCtx(), r.getR_Status_ID());
|
||||
if (status.getTimeoutDays() <= 0
|
||||
|| status.getNext_Status_ID() == 0)
|
||||
continue;
|
||||
// Next Status
|
||||
if (next == null || next.getR_Status_ID() != status.getNext_Status_ID())
|
||||
next = MStatus.get(getCtx(), status.getNext_Status_ID());
|
||||
//
|
||||
String result = Msg.getMsg(getCtx(), "RequestStatusTimeout")
|
||||
+ ": " + status.getName() + " -> " + next.getName();
|
||||
r.setResult(result);
|
||||
r.setR_Status_ID(status.getNext_Status_ID());
|
||||
if (r.save())
|
||||
count++;
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log (Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
m_summary.append("Status Timeout #").append(count)
|
||||
.append(" - ");
|
||||
} // processStatus
|
||||
|
||||
/**
|
||||
* Create ECR
|
||||
*/
|
||||
private void processECR()
|
||||
{
|
||||
// Get Requests with Request Type-AutoChangeRequest and Group with info
|
||||
String sql = "SELECT * FROM R_Request r "
|
||||
+ "WHERE M_ChangeRequest_ID IS NULL"
|
||||
+ " AND EXISTS ("
|
||||
+ "SELECT * FROM R_RequestType rt "
|
||||
+ "WHERE rt.R_RequestType_ID=r.R_RequestType_ID"
|
||||
+ " AND rt.IsAutoChangeRequest='Y')"
|
||||
+ "AND EXISTS ("
|
||||
+ "SELECT * FROM R_Group g "
|
||||
+ "WHERE g.R_Group_ID=r.R_Group_ID"
|
||||
+ " AND (g.M_BOM_ID IS NOT NULL OR g.M_ChangeNotice_ID IS NOT NULL) )";
|
||||
//
|
||||
int count = 0;
|
||||
int failure = 0;
|
||||
//
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MRequest r = new MRequest (getCtx(), rs, null);
|
||||
MGroup rg = MGroup.get(getCtx(), r.getR_Group_ID());
|
||||
MChangeRequest ecr = new MChangeRequest (r, rg);
|
||||
if (r.save())
|
||||
{
|
||||
r.setM_ChangeRequest_ID(ecr.getM_ChangeRequest_ID());
|
||||
if (r.save())
|
||||
count++;
|
||||
else
|
||||
failure++;
|
||||
}
|
||||
else
|
||||
failure++;
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log (Level.SEVERE, sql, e);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
m_summary.append("Auto Change Request #").append(count);
|
||||
if (failure > 0)
|
||||
m_summary.append("(fail=").append(failure).append(")");
|
||||
m_summary.append(" - ");
|
||||
} // processECR
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Create Reauest / Updates from EMail
|
||||
*/
|
||||
private void processEMail ()
|
||||
{
|
||||
// m_summary.append("Mail #").append(count)
|
||||
// .append(" - ");
|
||||
} // processEMail
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Allocate Sales Rep
|
||||
*/
|
||||
private void findSalesRep ()
|
||||
{
|
||||
int changed = 0;
|
||||
int notFound = 0;
|
||||
Properties ctx = new Properties();
|
||||
//
|
||||
String sql = "SELECT * FROM R_Request "
|
||||
+ "WHERE AD_Client_ID=?"
|
||||
+ " AND SalesRep_ID=0 AND Processed='N'";
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
sql += " AND R_RequestType_ID=?";
|
||||
PreparedStatement pstmt = null;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_Client_ID());
|
||||
if (m_model.getR_RequestType_ID() != 0)
|
||||
pstmt.setInt(2, m_model.getR_RequestType_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MRequest request = new MRequest (ctx, rs, null);
|
||||
if (request.getSalesRep_ID() != 0)
|
||||
continue;
|
||||
int SalesRep_ID = findSalesRep(request);
|
||||
if (SalesRep_ID != 0)
|
||||
{
|
||||
request.setSalesRep_ID(SalesRep_ID);
|
||||
request.save();
|
||||
changed++;
|
||||
}
|
||||
else
|
||||
notFound++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, ex);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException ex1)
|
||||
{
|
||||
}
|
||||
pstmt = null;
|
||||
//
|
||||
if (changed == 0 && notFound == 0)
|
||||
m_summary.append("No unallocated Requests");
|
||||
else
|
||||
m_summary.append("Allocated SalesRep=").append(changed);
|
||||
if (notFound > 0)
|
||||
m_summary.append(",Not=").append(notFound);
|
||||
m_summary.append(" - ");
|
||||
} // findSalesRep
|
||||
|
||||
/**
|
||||
* Find SalesRep/User based on Request Type and Question.
|
||||
* @param request request
|
||||
* @return SalesRep_ID user
|
||||
*/
|
||||
private int findSalesRep (MRequest request)
|
||||
{
|
||||
String QText = request.getSummary();
|
||||
if (QText == null)
|
||||
QText = "";
|
||||
else
|
||||
QText = QText.toUpperCase();
|
||||
//
|
||||
MRequestProcessorRoute[] routes = m_model.getRoutes(false);
|
||||
for (int i = 0; i < routes.length; i++)
|
||||
{
|
||||
MRequestProcessorRoute route = routes[i];
|
||||
|
||||
// Match first on Request Type
|
||||
if (request.getR_RequestType_ID() == route.getR_RequestType_ID()
|
||||
&& route.getR_RequestType_ID() != 0)
|
||||
return route.getAD_User_ID();
|
||||
|
||||
// Match on element of keyword
|
||||
String keyword = route.getKeyword();
|
||||
if (keyword != null)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(keyword.toUpperCase(), " ,;\t\n\r\f");
|
||||
while (st.hasMoreElements())
|
||||
{
|
||||
if (QText.indexOf(st.nextToken()) != -1)
|
||||
return route.getAD_User_ID();
|
||||
}
|
||||
}
|
||||
} // for all routes
|
||||
|
||||
return m_model.getSupervisor_ID();
|
||||
} // findSalesRep
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString();
|
||||
} // getServerInfo
|
||||
|
||||
} // RequestProcessor
|
|
@ -0,0 +1,290 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.logging.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.print.*;
|
||||
import org.compiere.process.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Scheduler
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Scheduler.java,v 1.5 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class Scheduler extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* Scheduler
|
||||
* @param model model
|
||||
*/
|
||||
public Scheduler (MScheduler model)
|
||||
{
|
||||
super (model, 240); // nap
|
||||
m_model = model;
|
||||
// m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
|
||||
} // Scheduler
|
||||
|
||||
/** The Concrete Model */
|
||||
private MScheduler m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Transaction */
|
||||
private Trx m_trx = null;
|
||||
|
||||
/**
|
||||
* Work
|
||||
*/
|
||||
protected void doWork ()
|
||||
{
|
||||
m_summary = new StringBuffer(m_model.toString())
|
||||
.append(" - ");
|
||||
//
|
||||
MProcess process = m_model.getProcess();
|
||||
try
|
||||
{
|
||||
m_trx = Trx.get(Trx.createTrxName("Scheduler"), true);
|
||||
if (process.isReport())
|
||||
m_summary.append(runReport(process));
|
||||
else
|
||||
m_summary.append(runProcess(process));
|
||||
m_trx.commit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (m_trx != null)
|
||||
m_trx.rollback();
|
||||
log.log(Level.WARNING, process.toString(), e);
|
||||
m_summary.append(e.toString());
|
||||
}
|
||||
if (m_trx != null)
|
||||
m_trx.close();
|
||||
//
|
||||
int no = m_model.deleteLog();
|
||||
m_summary.append("Logs deleted=").append(no);
|
||||
//
|
||||
MSchedulerLog pLog = new MSchedulerLog(m_model, m_summary.toString());
|
||||
pLog.setReference("#" + String.valueOf(p_runCount)
|
||||
+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
|
||||
pLog.save();
|
||||
} // doWork
|
||||
|
||||
/**
|
||||
* Run Report
|
||||
* @param process
|
||||
* @return summary
|
||||
* @throws Exception
|
||||
*/
|
||||
private String runReport(MProcess process) throws Exception
|
||||
{ log.info(process.toString());
|
||||
if (!process.isReport() || process.getAD_ReportView_ID() == 0)
|
||||
return "Not a Report AD_Process_ID=" + process.getAD_Process_ID()
|
||||
+ " - " + process.getName();
|
||||
// Process
|
||||
int AD_Table_ID = 0;
|
||||
int Record_ID = 0;
|
||||
//
|
||||
MPInstance pInstance = new MPInstance(process, Record_ID);
|
||||
fillParameter(pInstance);
|
||||
//
|
||||
ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(),
|
||||
AD_Table_ID, Record_ID);
|
||||
pi.setAD_User_ID(m_model.getUpdatedBy());
|
||||
pi.setAD_Client_ID(m_model.getAD_Client_ID());
|
||||
pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
|
||||
if (!process.processIt(pi, m_trx) && pi.getClassName() != null)
|
||||
return "Process failed: (" + pi.getClassName() + ") " + pi.getSummary();
|
||||
|
||||
// Report
|
||||
ReportEngine re = ReportEngine.get(getCtx(), pi);
|
||||
if (re == null)
|
||||
return "Cannot create Report AD_Process_ID=" + process.getAD_Process_ID()
|
||||
+ " - " + process.getName();
|
||||
File report = re.getPDF();
|
||||
// Notice
|
||||
int AD_Message_ID = 884; // HARDCODED SchedulerResult
|
||||
Integer[] userIDs = m_model.getRecipientAD_User_IDs();
|
||||
for (int i = 0; i < userIDs.length; i++)
|
||||
{
|
||||
MNote note = new MNote(getCtx(),
|
||||
AD_Message_ID, userIDs[i].intValue(), m_trx.getTrxName());
|
||||
note.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
|
||||
note.setTextMsg(m_model.getName());
|
||||
note.setDescription(m_model.getDescription());
|
||||
note.setRecord(AD_Table_ID, Record_ID);
|
||||
note.save();
|
||||
// Attachment
|
||||
MAttachment attachment = new MAttachment (getCtx(),
|
||||
X_AD_Note.Table_ID, note.getAD_Note_ID(), m_trx.getTrxName());
|
||||
attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
|
||||
attachment.addEntry(report);
|
||||
attachment.setTextMsg(m_model.getName());
|
||||
attachment.save();
|
||||
}
|
||||
//
|
||||
return pi.getSummary();
|
||||
} // runReport
|
||||
|
||||
/**
|
||||
* Run Process
|
||||
* @param process process
|
||||
* @return summary
|
||||
* @throws Exception
|
||||
*/
|
||||
private String runProcess(MProcess process) throws Exception
|
||||
{
|
||||
log.info(process.toString());
|
||||
// Process (see also MWFActivity.performWork
|
||||
int AD_Table_ID = 0;
|
||||
int Record_ID = 0;
|
||||
//
|
||||
MPInstance pInstance = new MPInstance(process, Record_ID);
|
||||
fillParameter(pInstance);
|
||||
//
|
||||
ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(),
|
||||
AD_Table_ID, Record_ID);
|
||||
pi.setAD_User_ID(m_model.getUpdatedBy());
|
||||
pi.setAD_Client_ID(m_model.getAD_Client_ID());
|
||||
pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
|
||||
process.processIt(pi, m_trx);
|
||||
return pi.getSummary();
|
||||
} // runProcess
|
||||
|
||||
/**
|
||||
* Fill Parameter
|
||||
* @param pInstance process instance
|
||||
*/
|
||||
private void fillParameter(MPInstance pInstance)
|
||||
{
|
||||
MSchedulerPara[] sParams = m_model.getParameters (false);
|
||||
MPInstancePara[] iParams = pInstance.getParameters();
|
||||
for (int pi = 0; pi < iParams.length; pi++)
|
||||
{
|
||||
MPInstancePara iPara = iParams[pi];
|
||||
for (int np = 0; np < sParams.length; np++)
|
||||
{
|
||||
MSchedulerPara sPara = sParams[np];
|
||||
if (iPara.getParameterName().equals(sPara.getColumnName()))
|
||||
{
|
||||
String variable = sPara.getParameterDefault();
|
||||
log.fine(sPara.getColumnName() + " = " + variable);
|
||||
// Value - Constant/Variable
|
||||
Object value = variable;
|
||||
if (variable == null
|
||||
|| (variable != null && variable.length() == 0))
|
||||
value = null;
|
||||
else if (variable.indexOf("@") != -1) // we have a variable
|
||||
{
|
||||
// Strip
|
||||
int index = variable.indexOf("@");
|
||||
String columnName = variable.substring(index+1);
|
||||
index = columnName.indexOf("@");
|
||||
if (index == -1)
|
||||
{
|
||||
log.warning(sPara.getColumnName()
|
||||
+ " - cannot evaluate=" + variable);
|
||||
break;
|
||||
}
|
||||
columnName = columnName.substring(0, index);
|
||||
// try Env
|
||||
String env = Env.getContext(getCtx(), columnName);
|
||||
if (env.length() == 0)
|
||||
{
|
||||
log.warning(sPara.getColumnName()
|
||||
+ " - not in environment =" + columnName
|
||||
+ "(" + variable + ")");
|
||||
break;
|
||||
}
|
||||
else
|
||||
value = env;
|
||||
} // @variable@
|
||||
|
||||
// No Value
|
||||
if (value == null)
|
||||
{
|
||||
log.fine(sPara.getColumnName() + " - empty");
|
||||
break;
|
||||
}
|
||||
|
||||
// Convert to Type
|
||||
try
|
||||
{
|
||||
if (DisplayType.isNumeric(sPara.getDisplayType())
|
||||
|| DisplayType.isID(sPara.getDisplayType()))
|
||||
{
|
||||
BigDecimal bd = null;
|
||||
if (value instanceof BigDecimal)
|
||||
bd = (BigDecimal)value;
|
||||
else if (value instanceof Integer)
|
||||
bd = new BigDecimal (((Integer)value).intValue());
|
||||
else
|
||||
bd = new BigDecimal (value.toString());
|
||||
iPara.setP_Number(bd);
|
||||
log.fine(sPara.getColumnName()
|
||||
+ " = " + variable + " (=" + bd + "=)");
|
||||
}
|
||||
else if (DisplayType.isDate(sPara.getDisplayType()))
|
||||
{
|
||||
Timestamp ts = null;
|
||||
if (value instanceof Timestamp)
|
||||
ts = (Timestamp)value;
|
||||
else
|
||||
ts = Timestamp.valueOf(value.toString());
|
||||
iPara.setP_Date(ts);
|
||||
log.fine(sPara.getColumnName()
|
||||
+ " = " + variable + " (=" + ts + "=)");
|
||||
}
|
||||
else
|
||||
{
|
||||
iPara.setP_String(value.toString());
|
||||
log.fine(sPara.getColumnName()
|
||||
+ " = " + variable
|
||||
+ " (=" + value + "=) " + value.getClass().getName());
|
||||
}
|
||||
if (!iPara.save())
|
||||
log.warning("Not Saved - " + sPara.getColumnName());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warning(sPara.getColumnName()
|
||||
+ " = " + variable + " (" + value
|
||||
+ ") " + value.getClass().getName()
|
||||
+ " - " + e.getLocalizedMessage());
|
||||
}
|
||||
break;
|
||||
} // parameter match
|
||||
} // scheduler parameter loop
|
||||
} // instance parameter loop
|
||||
} // fillParameter
|
||||
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString();
|
||||
} // getServerInfo
|
||||
|
||||
} // Scheduler
|
|
@ -0,0 +1,485 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.server;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import java.util.logging.*;
|
||||
import org.compiere.util.*;
|
||||
import org.compiere.wf.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.process.*;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Processor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: WorkflowProcessor.java,v 1.4 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class WorkflowProcessor extends AdempiereServer
|
||||
{
|
||||
/**
|
||||
* WorkflowProcessor
|
||||
* @param model model
|
||||
*/
|
||||
public WorkflowProcessor (MWorkflowProcessor model)
|
||||
{
|
||||
super (model, 120); // 2 minute dalay
|
||||
m_model = model;
|
||||
m_client = MClient.get(model.getCtx(), model.getAD_Client_ID());
|
||||
} // WorkflowProcessor
|
||||
|
||||
/** The Concrete Model */
|
||||
private MWorkflowProcessor m_model = null;
|
||||
/** Last Summary */
|
||||
private StringBuffer m_summary = new StringBuffer();
|
||||
/** Client onfo */
|
||||
private MClient m_client = null;
|
||||
|
||||
/**
|
||||
* Work
|
||||
*/
|
||||
protected void doWork ()
|
||||
{
|
||||
m_summary = new StringBuffer();
|
||||
//
|
||||
wakeup();
|
||||
dynamicPriority();
|
||||
sendAlerts();
|
||||
//
|
||||
int no = m_model.deleteLog();
|
||||
m_summary.append("Logs deleted=").append(no);
|
||||
//
|
||||
MWorkflowProcessorLog pLog = new MWorkflowProcessorLog(m_model, m_summary.toString());
|
||||
pLog.setReference("#" + String.valueOf(p_runCount)
|
||||
+ " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
|
||||
pLog.save();
|
||||
} // doWork
|
||||
|
||||
/**
|
||||
* Continue Workflow After Sleep
|
||||
*/
|
||||
private void wakeup()
|
||||
{
|
||||
String sql = "SELECT * "
|
||||
+ "FROM AD_WF_Activity a "
|
||||
+ "WHERE Processed='N' AND WFState='OS'" // suspended
|
||||
+ " AND EndWaitTime > SysDate"
|
||||
+ " AND AD_Client_ID=?"
|
||||
+ " AND EXISTS (SELECT * FROM AD_Workflow wf "
|
||||
+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
|
||||
+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
|
||||
+ " AND wfn.Action='Z'" // sleeping
|
||||
+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
|
||||
PreparedStatement pstmt = null;
|
||||
int count = 0;
|
||||
int countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt (1, m_model.getAD_Client_ID());
|
||||
pstmt.setInt (2, m_model.getAD_WorkflowProcessor_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MWFActivity activity = new MWFActivity (getCtx(), rs, null);
|
||||
activity.setWFState (StateEngine.STATE_Completed);
|
||||
// saves and calls MWFProcess.checkActivities();
|
||||
count++;
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "wakeup", e);
|
||||
}
|
||||
m_summary.append("Wakeup #").append(count).append (" - ");
|
||||
} // wakeup
|
||||
|
||||
/**
|
||||
* Set/Increase Priority dynamically
|
||||
*/
|
||||
private void dynamicPriority()
|
||||
{
|
||||
// suspened activities with dynamic priority node
|
||||
String sql = "SELECT * "
|
||||
+ "FROM AD_WF_Activity a "
|
||||
+ "WHERE Processed='N' AND WFState='OS'" // suspended
|
||||
+ " AND EXISTS (SELECT * FROM AD_Workflow wf"
|
||||
+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
|
||||
+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID AND wf.AD_WorkflowProcessor_ID=?"
|
||||
+ " AND wfn.DynPriorityUnit IS NOT NULL AND wfn.DynPriorityChange IS NOT NULL)";
|
||||
PreparedStatement pstmt = null;
|
||||
int count = 0;
|
||||
int countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_WorkflowProcessor_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MWFActivity activity = new MWFActivity (getCtx(), rs, null);
|
||||
if (activity.getDynPriorityStart() == 0)
|
||||
activity.setDynPriorityStart(activity.getPriority());
|
||||
long ms = System.currentTimeMillis() - activity.getCreated().getTime();
|
||||
MWFNode node = activity.getNode();
|
||||
int prioDiff = node.calculateDynamicPriority ((int)(ms / 1000));
|
||||
activity.setPriority(activity.getDynPriorityStart() + prioDiff);
|
||||
activity.save();
|
||||
count++;
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, sql, e);
|
||||
}
|
||||
m_summary.append("DynPriority #").append(count).append (" - ");
|
||||
|
||||
// Clean-up
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
} // setPriority
|
||||
|
||||
|
||||
/**
|
||||
* Send Alerts
|
||||
*/
|
||||
private void sendAlerts()
|
||||
{
|
||||
// Alert over Priority
|
||||
if (m_model.getAlertOverPriority() > 0)
|
||||
{
|
||||
String sql = "SELECT * "
|
||||
+ "FROM AD_WF_Activity a "
|
||||
+ "WHERE Processed='N' AND WFState='OS'" // suspended
|
||||
+ " AND Priority >= ?" // ##1
|
||||
+ " AND (DateLastAlert IS NULL";
|
||||
if (m_model.getRemindDays() > 0)
|
||||
sql += " OR (DateLastAlert+" + m_model.getRemindDays()
|
||||
+ ") < SysDate";
|
||||
sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
|
||||
+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
|
||||
+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
|
||||
+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
|
||||
int count = 0;
|
||||
int countEMails = 0;
|
||||
try
|
||||
{
|
||||
PreparedStatement pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt (1, m_model.getAlertOverPriority());
|
||||
pstmt.setInt (2, m_model.getAD_WorkflowProcessor_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MWFActivity activity = new MWFActivity (getCtx(), rs, null);
|
||||
boolean escalate = activity.getDateLastAlert() != null;
|
||||
countEMails += sendEmail (activity, "ActivityOverPriority",
|
||||
escalate, true);
|
||||
activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
|
||||
activity.save();
|
||||
count++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(Priority) - " + sql, e);
|
||||
}
|
||||
m_summary.append("OverPriority #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
} // Alert over Priority
|
||||
|
||||
/**
|
||||
* Over End Wait
|
||||
*/
|
||||
String sql = "SELECT * "
|
||||
+ "FROM AD_WF_Activity a "
|
||||
+ "WHERE Processed='N' AND WFState='OS'" // suspended
|
||||
+ " AND EndWaitTime > SysDate"
|
||||
+ " AND (DateLastAlert IS NULL";
|
||||
if (m_model.getRemindDays() > 0)
|
||||
sql += " OR (DateLastAlert+" + m_model.getRemindDays()
|
||||
+ ") < SysDate";
|
||||
sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
|
||||
+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
|
||||
+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
|
||||
+ " AND wfn.Action<>'Z'" // not sleeping
|
||||
+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
|
||||
PreparedStatement pstmt = null;
|
||||
int count = 0;
|
||||
int countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, null);
|
||||
pstmt.setInt(1, m_model.getAD_WorkflowProcessor_ID());
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
MWFActivity activity = new MWFActivity (getCtx(), rs, null);
|
||||
boolean escalate = activity.getDateLastAlert() != null;
|
||||
countEMails += sendEmail (activity, "ActivityEndWaitTime",
|
||||
escalate, false);
|
||||
activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
|
||||
activity.save();
|
||||
count++;
|
||||
}
|
||||
rs.close ();
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(EndWaitTime) - " + sql, e);
|
||||
}
|
||||
m_summary.append("EndWaitTime #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
|
||||
/**
|
||||
* Send inactivity alerts
|
||||
*/
|
||||
if (m_model.getInactivityAlertDays() > 0)
|
||||
{
|
||||
sql = "SELECT * "
|
||||
+ "FROM AD_WF_Activity a "
|
||||
+ "WHERE Processed='N' AND WFState='OS'" // suspended
|
||||
+ " AND (Updated+" + m_model.getInactivityAlertDays() + ") < SysDate"
|
||||
+ " AND (DateLastAlert IS NULL";
|
||||
if (m_model.getRemindDays() > 0)
|
||||
sql += " OR (DateLastAlert+" + m_model.getRemindDays()
|
||||
+ ") < SysDate";
|
||||
sql += ") AND EXISTS (SELECT * FROM AD_Workflow wf "
|
||||
+ " INNER JOIN AD_WF_Node wfn ON (wf.AD_Workflow_ID=wfn.AD_Workflow_ID) "
|
||||
+ "WHERE a.AD_WF_Node_ID=wfn.AD_WF_Node_ID"
|
||||
+ " AND wf.AD_WorkflowProcessor_ID IS NULL OR wf.AD_WorkflowProcessor_ID=?)";
|
||||
count = 0;
|
||||
countEMails = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt (1, m_model.getAD_WorkflowProcessor_ID());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
MWFActivity activity = new MWFActivity (getCtx(), rs, null);
|
||||
boolean escalate = activity.getDateLastAlert() != null;
|
||||
countEMails += sendEmail (activity, "ActivityInactivity",
|
||||
escalate, false);
|
||||
activity.setDateLastAlert(new Timestamp(System.currentTimeMillis()));
|
||||
activity.save();
|
||||
count++;
|
||||
}
|
||||
rs.close();
|
||||
pstmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.log(Level.SEVERE, "(Inactivity): " + sql, e);
|
||||
}
|
||||
m_summary.append("Inactivity #").append(count);
|
||||
if (countEMails > 0)
|
||||
m_summary.append(" (").append(countEMails).append(" EMail)");
|
||||
m_summary.append (" - ");
|
||||
} // Inactivity
|
||||
|
||||
|
||||
// Clean-up
|
||||
try
|
||||
{
|
||||
if (pstmt != null)
|
||||
pstmt.close ();
|
||||
pstmt = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
pstmt = null;
|
||||
}
|
||||
} // sendAlerts
|
||||
|
||||
/**
|
||||
* Send Alert EMail
|
||||
* @param activity activity
|
||||
* @param AD_Message message
|
||||
* @param toProcess true if to process owner
|
||||
* @param toSupervisor true if to Supervisor
|
||||
* @return number of mails sent
|
||||
*/
|
||||
private int sendEmail (MWFActivity activity, String AD_Message,
|
||||
boolean toProcess, boolean toSupervisor)
|
||||
{
|
||||
if (m_client == null || m_client.getAD_Client_ID() != activity.getAD_Client_ID())
|
||||
m_client = MClient.get(getCtx(), activity.getAD_Client_ID());
|
||||
|
||||
MWFProcess process = new MWFProcess (getCtx(), activity.getAD_WF_Process_ID(), null);
|
||||
|
||||
String subjectVar = activity.getNode().getName();
|
||||
String message = activity.getTextMsg();
|
||||
if (message == null || message.length() == 0)
|
||||
message = process.getTextMsg();
|
||||
File pdf = null;
|
||||
PO po = activity.getPO();
|
||||
if (po instanceof DocAction)
|
||||
{
|
||||
message = ((DocAction)po).getDocumentInfo() + "\n" + message;
|
||||
pdf = ((DocAction)po).createPDF();
|
||||
}
|
||||
|
||||
// Inactivity Alert: Workflow Activity {0}
|
||||
String subject = Msg.getMsg(m_client.getAD_Language(), AD_Message,
|
||||
new Object[] {subjectVar});
|
||||
|
||||
// Prevent duplicates
|
||||
ArrayList<Integer> list = new ArrayList<Integer>();
|
||||
int counter = 0;
|
||||
|
||||
// To Activity Owner
|
||||
if (m_client.sendEMail(activity.getAD_User_ID(), subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(activity.getAD_User_ID()));
|
||||
|
||||
// To Process Owner
|
||||
if (toProcess
|
||||
&& process.getAD_User_ID() != activity.getAD_User_ID())
|
||||
{
|
||||
if (m_client.sendEMail(process.getAD_User_ID(), subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(process.getAD_User_ID()));
|
||||
}
|
||||
|
||||
// To Activity Responsible
|
||||
MWFResponsible responsible = MWFResponsible.get(getCtx(), activity.getAD_WF_Responsible_ID());
|
||||
counter += sendAlertToResponsible (responsible, list, process,
|
||||
subject, message, pdf);
|
||||
|
||||
// To Process Responsible
|
||||
if (toProcess
|
||||
&& process.getAD_WF_Responsible_ID() != activity.getAD_WF_Responsible_ID())
|
||||
{
|
||||
responsible = MWFResponsible.get(getCtx(), process.getAD_WF_Responsible_ID());
|
||||
counter += sendAlertToResponsible (responsible, list, process,
|
||||
subject, message, pdf);
|
||||
}
|
||||
|
||||
// Processor SuperVisor
|
||||
if (toSupervisor
|
||||
&& m_model.getSupervisor_ID() != 0
|
||||
&& !list.contains(new Integer(m_model.getSupervisor_ID())))
|
||||
{
|
||||
if (m_client.sendEMail(m_model.getSupervisor_ID(), subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(m_model.getSupervisor_ID()));
|
||||
}
|
||||
|
||||
return counter;
|
||||
} // sendAlert
|
||||
|
||||
/**
|
||||
* Send Alert To Responsible
|
||||
* @param responsible responsible
|
||||
* @param list list of already sent users
|
||||
* @param process process
|
||||
* @param subject subject
|
||||
* @param message message
|
||||
* @param pdf optional pdf
|
||||
* @return number of mail sent
|
||||
*/
|
||||
private int sendAlertToResponsible (MWFResponsible responsible,
|
||||
ArrayList<Integer> list, MWFProcess process,
|
||||
String subject, String message, File pdf)
|
||||
{
|
||||
int counter = 0;
|
||||
if (responsible.isInvoker())
|
||||
;
|
||||
// Human
|
||||
else if (MWFResponsible.RESPONSIBLETYPE_Human.equals(responsible.getResponsibleType())
|
||||
&& responsible.getAD_User_ID() != 0
|
||||
&& !list.contains(new Integer(responsible.getAD_User_ID())))
|
||||
{
|
||||
if (m_client.sendEMail(responsible.getAD_User_ID(), subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(responsible.getAD_User_ID()));
|
||||
}
|
||||
// Org of the Document
|
||||
else if (MWFResponsible.RESPONSIBLETYPE_Organization.equals(responsible.getResponsibleType()))
|
||||
{
|
||||
PO document = process.getPO();
|
||||
if (document != null)
|
||||
{
|
||||
MOrgInfo org = MOrgInfo.get (getCtx(), document.getAD_Org_ID());
|
||||
if (org.getSupervisor_ID() != 0
|
||||
&& !list.contains(new Integer(org.getSupervisor_ID())))
|
||||
{
|
||||
if (m_client.sendEMail(org.getSupervisor_ID(), subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(org.getSupervisor_ID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Role
|
||||
else if (MWFResponsible.RESPONSIBLETYPE_Role.equals(responsible.getResponsibleType())
|
||||
&& responsible.getAD_Role_ID() != 0)
|
||||
{
|
||||
MUserRoles[] userRoles = MUserRoles.getOfRole(getCtx(), responsible.getAD_Role_ID());
|
||||
for (int i = 0; i < userRoles.length; i++)
|
||||
{
|
||||
MUserRoles roles = userRoles[i];
|
||||
if (!roles.isActive())
|
||||
continue;
|
||||
int AD_User_ID = roles.getAD_User_ID();
|
||||
if (!list.contains(new Integer(AD_User_ID)))
|
||||
{
|
||||
if (m_client.sendEMail(AD_User_ID, subject, message, pdf))
|
||||
counter++;
|
||||
list.add (new Integer(AD_User_ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
} // sendAlertToResponsible
|
||||
|
||||
|
||||
/**
|
||||
* Get Server Info
|
||||
* @return info
|
||||
*/
|
||||
public String getServerInfo()
|
||||
{
|
||||
return "#" + p_runCount + " - Last=" + m_summary.toString();
|
||||
} // getServerInfo
|
||||
|
||||
} // WorkflowProcessor
|
|
@ -0,0 +1,869 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import org.apache.ecs.*;
|
||||
import org.apache.ecs.xhtml.*;
|
||||
import org.compiere.*;
|
||||
import org.compiere.db.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.server.*;
|
||||
import org.compiere.util.*;
|
||||
|
||||
/**
|
||||
* Adempiere Server Monitor
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AdempiereMonitor.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class AdempiereMonitor extends HttpServlet
|
||||
{
|
||||
/** Logger */
|
||||
private static CLogger log = CLogger.getCLogger(AdempiereMonitor.class);
|
||||
/** The Server */
|
||||
private AdempiereServerMgr m_serverMgr = null;
|
||||
/** Message */
|
||||
private p m_message = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @throws javax.servlet.ServletException
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
protected void doGet (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
m_message = null;
|
||||
if (processLogParameter (request, response))
|
||||
return;
|
||||
if (processTraceParameter (request, response))
|
||||
return;
|
||||
if (processEMailParameter (request, response))
|
||||
return;
|
||||
if (processCacheParameter (request, response))
|
||||
return;
|
||||
//
|
||||
if (processRunNowParameter (request))
|
||||
;
|
||||
else
|
||||
processActionParameter (request);
|
||||
createSummaryPage(request, response);
|
||||
} // doGet
|
||||
|
||||
/**
|
||||
* Post
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void doPost (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
doGet(request, response);
|
||||
} // doPost
|
||||
|
||||
/**
|
||||
* Process Log Parameter and return log page
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @return true if it was a log request
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean processLogParameter (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String serverID = WebUtil.getParameter (request, "Log");
|
||||
if (serverID == null || serverID.length() == 0)
|
||||
return false;
|
||||
|
||||
log.info ("ServerID=" + serverID);
|
||||
AdempiereServer server = m_serverMgr.getServer(serverID);
|
||||
if (server == null)
|
||||
{
|
||||
m_message = new p();
|
||||
m_message.addElement(new strong("Server not found: "));
|
||||
m_message.addElement(serverID);
|
||||
return false;
|
||||
}
|
||||
|
||||
WebDoc doc = WebDoc.create ("Adempiere Server Monitor Log");
|
||||
// Body
|
||||
body b = doc.getBody();
|
||||
//
|
||||
p para = new p();
|
||||
a link = new a ("adempiereMonitor#" + serverID, "Return");
|
||||
para.addElement(link);
|
||||
b.addElement(para);
|
||||
//
|
||||
b.addElement(new h2(server.getName()));
|
||||
//
|
||||
table table = new table();
|
||||
table.setBorder(1);
|
||||
table.setCellSpacing(2);
|
||||
table.setCellPadding(2);
|
||||
|
||||
// Header
|
||||
tr line = new tr();
|
||||
line.addElement(new th().addElement("Created"));
|
||||
line.addElement(new th().addElement("Summary"));
|
||||
// line.addElement(new th().addElement("Error"));
|
||||
line.addElement(new th().addElement("Reference"));
|
||||
line.addElement(new th().addElement("TextMsg"));
|
||||
// line.addElement(new th().addElement("Description"));
|
||||
table.addElement(line);
|
||||
|
||||
AdempiereProcessorLog[] logs = server.getLogs();
|
||||
for (int i = 0; i < logs.length; i++)
|
||||
{
|
||||
AdempiereProcessorLog pLog = logs[i];
|
||||
line = new tr();
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(pLog.getCreated())));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(pLog.getSummary())));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(pLog.getReference())));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(pLog.getTextMsg())));
|
||||
table.addElement(line);
|
||||
}
|
||||
//
|
||||
b.addElement(table);
|
||||
link = new a ("#top", "Top");
|
||||
b.addElement(link);
|
||||
|
||||
// fini
|
||||
WebUtil.createResponse (request, response, this, null, doc, false);
|
||||
return true;
|
||||
} // processLogParameter
|
||||
|
||||
/**
|
||||
* Process Run Parameter
|
||||
* @param request request
|
||||
* @return true if it was a Run request
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean processRunNowParameter (HttpServletRequest request)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String serverID = WebUtil.getParameter (request, "RunNow");
|
||||
if (serverID == null || serverID.length() == 0)
|
||||
return false;
|
||||
|
||||
log.info ("ServerID=" + serverID);
|
||||
AdempiereServer server = m_serverMgr.getServer(serverID);
|
||||
if (server == null)
|
||||
{
|
||||
m_message = new p();
|
||||
m_message.addElement(new strong("Server not found: "));
|
||||
m_message.addElement(serverID);
|
||||
return false;
|
||||
}
|
||||
//
|
||||
server.runNow();
|
||||
//
|
||||
return true;
|
||||
} // processRunParameter
|
||||
|
||||
/**
|
||||
* Process Action Parameter
|
||||
* @param request request
|
||||
*/
|
||||
private void processActionParameter (HttpServletRequest request)
|
||||
{
|
||||
String action = WebUtil.getParameter (request, "Action");
|
||||
if (action == null || action.length() == 0)
|
||||
return;
|
||||
log.info ("Action=" + action);
|
||||
try
|
||||
{
|
||||
boolean start = action.startsWith("Start");
|
||||
m_message = new p();
|
||||
String msg = (start ? "Started" : "Stopped") + ": ";
|
||||
m_message.addElement(new strong(msg));
|
||||
//
|
||||
String serverID = action.substring(action.indexOf("_")+1);
|
||||
boolean ok = false;
|
||||
if (serverID.equals("All"))
|
||||
{
|
||||
if (start)
|
||||
ok = m_serverMgr.startAll();
|
||||
else
|
||||
ok = m_serverMgr.stopAll();
|
||||
m_message.addElement("All");
|
||||
}
|
||||
else
|
||||
{
|
||||
AdempiereServer server = m_serverMgr.getServer(serverID);
|
||||
if (server == null)
|
||||
{
|
||||
m_message = new p();
|
||||
m_message.addElement(new strong("Server not found: "));
|
||||
m_message.addElement(serverID);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (start)
|
||||
ok = m_serverMgr.start (serverID);
|
||||
else
|
||||
ok = m_serverMgr.stop (serverID);
|
||||
m_message.addElement(server.getName());
|
||||
}
|
||||
}
|
||||
m_message.addElement(ok ? " - OK" : " - Error!");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_message = new p();
|
||||
m_message.addElement(new strong("Error processing parameter: " + action));
|
||||
m_message.addElement(new br());
|
||||
m_message.addElement(e.toString());
|
||||
}
|
||||
} // processActionParameter
|
||||
|
||||
/**
|
||||
* Process Trace Parameter
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @return true if it was a trace request with output
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean processTraceParameter (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String traceCmd = WebUtil.getParameter (request, "Trace");
|
||||
String traceLevel = WebUtil.getParameter (request, "TraceLevel");
|
||||
if (traceLevel != null && traceLevel.length() > 0)
|
||||
{
|
||||
log.info ("New Level: " + traceLevel);
|
||||
CLogMgt.setLevel(traceLevel);
|
||||
Ini.setProperty(Ini.P_TRACELEVEL, traceLevel);
|
||||
Ini.saveProperties(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (traceCmd == null || traceCmd.length() == 0)
|
||||
return false;
|
||||
|
||||
log.info ("Command: " + traceCmd);
|
||||
CLogFile fileHandler = CLogFile.get (false, null, false);
|
||||
//
|
||||
if (traceCmd.equals("ROTATE"))
|
||||
{
|
||||
if (fileHandler != null)
|
||||
fileHandler.rotateLog();
|
||||
return false; // re-display
|
||||
}
|
||||
else if (traceCmd.equals("DELETE"))
|
||||
{
|
||||
File logDir = fileHandler.getLogDirectory();
|
||||
if (logDir != null && logDir.isDirectory())
|
||||
{
|
||||
File[] logs = logDir.listFiles();
|
||||
for (int i = 0; i < logs.length; i++)
|
||||
{
|
||||
String fileName = logs[i].getAbsolutePath();
|
||||
if (fileName.equals(fileHandler.getFileName()))
|
||||
continue;
|
||||
if (logs[i].delete())
|
||||
log.warning("Deleted: " + fileName);
|
||||
else
|
||||
log.warning("Not Deleted: " + fileName);
|
||||
}
|
||||
}
|
||||
return false; // re-display
|
||||
}
|
||||
|
||||
// Display current log File
|
||||
if (fileHandler != null && fileHandler.getFileName().equals(traceCmd))
|
||||
fileHandler.flush();
|
||||
|
||||
// Spool File
|
||||
File file = new File (traceCmd);
|
||||
if (!file.exists())
|
||||
{
|
||||
log.warning ("Did not find File: " + traceCmd);
|
||||
return false;
|
||||
}
|
||||
if (file.length() == 0)
|
||||
{
|
||||
log.warning ("File Length=0: " + traceCmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stream Log
|
||||
log.info ("Streaming: " + traceCmd);
|
||||
try
|
||||
{
|
||||
long time = System.currentTimeMillis(); // timer start
|
||||
int fileLength = (int)file.length();
|
||||
int bufferSize = 2048; // 2k Buffer
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
//
|
||||
response.setContentType("text/plain");
|
||||
response.setBufferSize(bufferSize);
|
||||
response.setContentLength(fileLength);
|
||||
//
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ServletOutputStream out = response.getOutputStream ();
|
||||
int read = 0;
|
||||
while ((read = fis.read(buffer)) > 0)
|
||||
out.write (buffer, 0, read);
|
||||
out.flush();
|
||||
out.close();
|
||||
fis.close();
|
||||
//
|
||||
time = System.currentTimeMillis() - time;
|
||||
double speed = (fileLength/1024) / ((double)time/1000);
|
||||
log.info("length="
|
||||
+ fileLength + " - "
|
||||
+ time + " ms - "
|
||||
+ speed + " kB/sec");
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.log(Level.SEVERE, "stream" + ex);
|
||||
}
|
||||
return true;
|
||||
} // processTraceParameter
|
||||
|
||||
/**
|
||||
* Process EMail Parameter
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @return true if it was a email request with output
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean processEMailParameter (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String email = WebUtil.getParameter (request, "EMail");
|
||||
if (email == null || email.length() == 0)
|
||||
return false;
|
||||
|
||||
int AD_Client_ID = -1;
|
||||
try
|
||||
{
|
||||
AD_Client_ID = Integer.parseInt(email);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warning("Parsing: " + email + " - " + e.toString());
|
||||
}
|
||||
if (AD_Client_ID < 0)
|
||||
{
|
||||
m_message = new p();
|
||||
m_message.addElement("No EMail: " + email);
|
||||
return false;
|
||||
}
|
||||
|
||||
// log.info ("Test EMail: " + AD_Client_ID);
|
||||
MClient client = MClient.get(new Properties(), AD_Client_ID);
|
||||
log.info ("Test: " + client);
|
||||
|
||||
m_message = new p();
|
||||
m_message.addElement(client.getName() + ": " + client.testEMail());
|
||||
return false;
|
||||
} // processEMailParameter
|
||||
|
||||
|
||||
/**
|
||||
* Process Cache Parameter
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @return true if it was a email request with output
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean processCacheParameter (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
String cmd = WebUtil.getParameter (request, "CacheReset");
|
||||
if (cmd == null || cmd.length() == 0)
|
||||
return false;
|
||||
String tableName = WebUtil.getParameter (request, "CacheTableName");
|
||||
String record_ID = WebUtil.getParameter (request, "CacheRecord_ID");
|
||||
|
||||
m_message = new p();
|
||||
try
|
||||
{
|
||||
if (tableName == null || tableName.length() == 0)
|
||||
{
|
||||
CacheMgt.get().reset();
|
||||
m_message.addElement("Cache Reset: All");
|
||||
}
|
||||
else if (record_ID == null || record_ID.length() == 0)
|
||||
{
|
||||
CacheMgt.get().reset(tableName);
|
||||
m_message.addElement("Cache Reset: " + tableName);
|
||||
}
|
||||
else
|
||||
{
|
||||
CacheMgt.get().reset(tableName, Integer.parseInt(record_ID));
|
||||
m_message.addElement("Cache Reset: " + tableName + ", Record_ID=" + record_ID);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.severe(e.toString());
|
||||
m_message.addElement("Error: " + e.toString());
|
||||
}
|
||||
return false; // continue
|
||||
} // processEMailParameter
|
||||
|
||||
/**************************************************************************
|
||||
* Create & Return Summary Page
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void createSummaryPage (HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
WebDoc doc = WebDoc.create ("Adempiere Server Monitor");
|
||||
// log.info("ServletConfig=" + getServletConfig());
|
||||
// AdempiereServerGroup.get().dump();
|
||||
|
||||
// Body
|
||||
body bb = doc.getBody();
|
||||
// Message
|
||||
if (m_message != null)
|
||||
{
|
||||
bb.addElement(new hr());
|
||||
bb.addElement(m_message);
|
||||
bb.addElement(new hr());
|
||||
}
|
||||
|
||||
// Summary
|
||||
table table = new table();
|
||||
table.setBorder(1);
|
||||
table.setCellSpacing(2);
|
||||
table.setCellPadding(2);
|
||||
//
|
||||
tr line = new tr();
|
||||
line.addElement(new th().addElement(Adempiere.getName()));
|
||||
line.addElement(new td().addElement(Adempiere.getVersion()));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement(Adempiere.getImplementationVendor()));
|
||||
line.addElement(new td().addElement(Adempiere.getImplementationVersion()));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Manager"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(m_serverMgr.getDescription())));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Start - Elapsed"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(m_serverMgr.getStartTime())
|
||||
+ " - " + TimeUtil.formatElapsed(m_serverMgr.getStartTime())));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Servers"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(m_serverMgr.getServerCount())));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Last Updated"));
|
||||
line.addElement(new td().addElement(new Timestamp(System.currentTimeMillis()).toString()));
|
||||
table.addElement(line);
|
||||
bb.addElement(table);
|
||||
//
|
||||
p para = new p();
|
||||
a link = new a ("adempiereMonitor?Action=Start_All", "Start All");
|
||||
para.addElement(link);
|
||||
para.addElement(" - ");
|
||||
link = new a ("adempiereMonitor?Action=Stop_All", "Stop All");
|
||||
para.addElement(link);
|
||||
para.addElement(" - ");
|
||||
link = new a ("adempiereMonitor", "Refresh");
|
||||
para.addElement(link);
|
||||
bb.addElement(para);
|
||||
|
||||
// ***** Server Links *****
|
||||
bb.addElement(new hr());
|
||||
para = new p();
|
||||
AdempiereServer[] servers = m_serverMgr.getAll();
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
para.addElement(new br());
|
||||
AdempiereServer server = servers[i];
|
||||
link = new a ("#" + server.getServerID(), server.getName());
|
||||
para.addElement(link);
|
||||
font status = null;
|
||||
if (server.isAlive())
|
||||
status = new font().setColor(HtmlColor.GREEN).addElement(" (Running)");
|
||||
else
|
||||
status = new font().setColor(HtmlColor.RED).addElement(" (Stopped)");
|
||||
para.addElement(status);
|
||||
}
|
||||
bb.addElement(para);
|
||||
|
||||
// **** Log Management ****
|
||||
createLogMgtPage(bb);
|
||||
|
||||
// ***** Server Details *****
|
||||
for (int i = 0; i < servers.length; i++)
|
||||
{
|
||||
AdempiereServer server = servers[i];
|
||||
bb.addElement(new hr());
|
||||
bb.addElement(new a().setName(server.getServerID()));
|
||||
bb.addElement(new h2(server.getName()));
|
||||
//
|
||||
table = new table();
|
||||
table.setBorder(1);
|
||||
table.setCellSpacing(2);
|
||||
table.setCellPadding(2);
|
||||
// Status
|
||||
line = new tr();
|
||||
if (server.isAlive())
|
||||
{
|
||||
String msg = "Stop";
|
||||
if (server.isInterrupted())
|
||||
msg += " (Interrupted)";
|
||||
link = new a ("adempiereMonitor?Action=Stop_" + server.getServerID(), msg);
|
||||
if (server.isSleeping())
|
||||
{
|
||||
line.addElement(new th().addElement("Sleeping"));
|
||||
line.addElement(new td().addElement(link));
|
||||
}
|
||||
else
|
||||
{
|
||||
line.addElement(new th().addElement("Running"));
|
||||
line.addElement(new td().addElement(link));
|
||||
}
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Start - Elapsed"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(server.getStartTime())
|
||||
+ " - " + TimeUtil.formatElapsed(server.getStartTime())));
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = "Start";
|
||||
if (server.isInterrupted())
|
||||
msg += " (Interrupted)";
|
||||
line.addElement(new th().addElement("Not Started"));
|
||||
link = new a ("adempiereMonitor?Action=Start_" + server.getServerID(), msg);
|
||||
line.addElement(new td().addElement(link));
|
||||
}
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Description"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(server.getDescription())));
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Last Run"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(server.getDateLastRun())));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Info"));
|
||||
line.addElement(new td().addElement(WebEnv.getCellContent(server.getServerInfo())));
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Next Run"));
|
||||
td td = new td();
|
||||
td.addElement(WebEnv.getCellContent(server.getDateNextRun(false)));
|
||||
td.addElement(" - ");
|
||||
link = new a ("adempiereMonitor?RunNow=" + server.getServerID(), "(Run Now)");
|
||||
td.addElement(link);
|
||||
line.addElement(td);
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Statistics"));
|
||||
line.addElement(new td().addElement(server.getStatistics()));
|
||||
table.addElement(line);
|
||||
//
|
||||
|
||||
// Add table to Body
|
||||
bb.addElement(table);
|
||||
link = new a ("#top", "Top");
|
||||
bb.addElement(link);
|
||||
bb.addElement(" - ");
|
||||
link = new a ("adempiereMonitor?Log=" + server.getServerID(), "Log");
|
||||
bb.addElement(link);
|
||||
bb.addElement(" - ");
|
||||
link = new a ("adempiereMonitor", "Refresh");
|
||||
bb.addElement(link);
|
||||
}
|
||||
|
||||
// fini
|
||||
WebUtil.createResponse (request, response, this, null, doc, false);
|
||||
} // createSummaryPage
|
||||
|
||||
/**
|
||||
* Add Log Management to page
|
||||
* @param bb body
|
||||
*/
|
||||
private void createLogMgtPage (body bb)
|
||||
{
|
||||
bb.addElement(new hr());
|
||||
|
||||
// Ini Parameters
|
||||
table table = new table();
|
||||
table.setBorder(1);
|
||||
table.setCellSpacing(2);
|
||||
table.setCellPadding(2);
|
||||
//
|
||||
Properties ctx = new Properties();
|
||||
MSystem system = MSystem.get(ctx);
|
||||
tr line = new tr();
|
||||
line.addElement(new th().addElement(system.getDBAddress()));
|
||||
line.addElement(new td().addElement(Ini.getAdempiereHome()));
|
||||
table.addElement(line);
|
||||
// OS + Name
|
||||
line = new tr();
|
||||
String info = System.getProperty("os.name")
|
||||
+ " " + System.getProperty("os.version");
|
||||
String s = System.getProperty("sun.os.patch.level");
|
||||
if (s != null && s.length() > 0)
|
||||
info += " (" + s + ")";
|
||||
line.addElement(new th().addElement(info));
|
||||
info = system.getName();
|
||||
if (system.getCustomPrefix() != null)
|
||||
info += " (" + system.getCustomPrefix() + ")";
|
||||
line.addElement(new td().addElement(info));
|
||||
table.addElement(line);
|
||||
// Java + email
|
||||
line = new tr();
|
||||
info = System.getProperty("java.vm.name")
|
||||
+ " " + System.getProperty("java.vm.version");
|
||||
line.addElement(new th().addElement(info));
|
||||
line.addElement(new td().addElement(system.getUserName()));
|
||||
table.addElement(line);
|
||||
// DB + Instance
|
||||
line = new tr();
|
||||
CConnection cc = CConnection.get();
|
||||
AdempiereDatabase db = cc.getDatabase();
|
||||
info = db.getDescription();
|
||||
line.addElement(new th().addElement(info));
|
||||
line.addElement(new td().addElement(cc.getConnectionURL()));
|
||||
// line.addElement(new td().addElement(system.getDBInstance()));
|
||||
table.addElement(line);
|
||||
// Processors/Support
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Processor/Support"));
|
||||
line.addElement(new td().addElement(system.getNoProcessors() + "/" + system.getSupportUnits()));
|
||||
table.addElement(line);
|
||||
// Memory
|
||||
line = new tr();
|
||||
MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
|
||||
line.addElement(new th().addElement("VM Memory"));
|
||||
line.addElement(new td().addElement(new CMemoryUsage(memory.getNonHeapMemoryUsage()).toString()));
|
||||
table.addElement(line);
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement("Heap Memory"));
|
||||
line.addElement(new td().addElement(new CMemoryUsage(memory.getHeapMemoryUsage()).toString()));
|
||||
table.addElement(line);
|
||||
// Runtime
|
||||
line = new tr();
|
||||
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
|
||||
line.addElement(new th().addElement("Runtime " + rt.getName()));
|
||||
line.addElement(new td().addElement(TimeUtil.formatElapsed(rt.getUptime())));
|
||||
table.addElement(line);
|
||||
// Threads
|
||||
line = new tr();
|
||||
ThreadMXBean th = ManagementFactory.getThreadMXBean();
|
||||
line.addElement(new th().addElement("Threads " + th.getThreadCount()));
|
||||
line.addElement(new td().addElement("Peak=" + th.getPeakThreadCount()
|
||||
+ ", Demons=" + th.getDaemonThreadCount()
|
||||
+ ", Total=" + th.getTotalStartedThreadCount()));
|
||||
table.addElement(line);
|
||||
// Cache Reset
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement(CacheMgt.get().toStringX()));
|
||||
line.addElement(new td().addElement(new a ("adempiereMonitor?CacheReset=Yes", "Reset Cache")));
|
||||
table.addElement(line);
|
||||
|
||||
// Trace Level
|
||||
line = new tr();
|
||||
line.addElement(new th().addElement(new label("TraceLevel").addElement("Trace Log Level")));
|
||||
form myForm = new form("adempiereMonitor", form.METHOD_POST, form.ENC_DEFAULT);
|
||||
// LogLevel Selection
|
||||
option[] options = new option[CLogMgt.LEVELS.length];
|
||||
for (int i = 0; i < options.length; i++)
|
||||
{
|
||||
options[i] = new option(CLogMgt.LEVELS[i].getName());
|
||||
options[i].addElement(CLogMgt.LEVELS[i].getName());
|
||||
if (CLogMgt.LEVELS[i] == CLogMgt.getLevel())
|
||||
options[i].setSelected(true);
|
||||
}
|
||||
select sel = new select("TraceLevel", options);
|
||||
myForm.addElement(sel);
|
||||
myForm.addElement(new input(input.TYPE_SUBMIT, "Set", "Set"));
|
||||
line.addElement(new td().addElement(myForm));
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
CLogFile fileHandler = CLogFile.get (true, null, false);
|
||||
line.addElement(new th().addElement("Trace File"));
|
||||
line.addElement(new td().addElement(new a ("adempiereMonitor?Trace=" + fileHandler.getFileName(), "Current")));
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
line.addElement(new td().addElement(new a ("adempiereMonitor?Trace=ROTATE", "Rotate Trace Log")));
|
||||
line.addElement(new td().addElement(new a ("adempiereMonitor?Trace=DELETE", "Delete all Trace Logs")));
|
||||
table.addElement(line);
|
||||
//
|
||||
bb.addElement(table);
|
||||
|
||||
// List Log Files
|
||||
p p = new p();
|
||||
p.addElement(new b("All Log Files: "));
|
||||
// All in dir
|
||||
File logDir = fileHandler.getLogDirectory();
|
||||
if (logDir != null && logDir.isDirectory())
|
||||
{
|
||||
File[] logs = logDir.listFiles();
|
||||
for (int i = 0; i < logs.length; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
p.addElement(" - ");
|
||||
String fileName = logs[i].getAbsolutePath();
|
||||
a link = new a ("adempiereMonitor?Trace=" + fileName, fileName);
|
||||
p.addElement(link);
|
||||
int size = (int)(logs[i].length()/1024);
|
||||
if (size < 1024)
|
||||
p.addElement(" (" + size + "k)");
|
||||
else
|
||||
p.addElement(" (" + size/1024 + "M)");
|
||||
}
|
||||
}
|
||||
bb.addElement(p);
|
||||
|
||||
// Clients and Web Stores
|
||||
table = new table();
|
||||
table.setBorder(1);
|
||||
table.setCellSpacing(2);
|
||||
table.setCellPadding(2);
|
||||
//
|
||||
line = new tr();
|
||||
MClient[] clients = MClient.getAll(ctx);
|
||||
line.addElement(new th().addElement("Client #" + clients.length + " - EMail Test:"));
|
||||
p = new p();
|
||||
for (int i = 0; i < clients.length; i++)
|
||||
{
|
||||
MClient client = clients[i];
|
||||
if (i > 0)
|
||||
p.addElement(" - ");
|
||||
p.addElement(new a("adempiereMonitor?EMail=" + client.getAD_Client_ID(), client.getName()));
|
||||
}
|
||||
if (clients.length == 0)
|
||||
p.addElement(" ");
|
||||
line.addElement(new td().addElement(p));
|
||||
table.addElement(line);
|
||||
//
|
||||
line = new tr();
|
||||
MStore[] wstores = MStore.getActive();
|
||||
line.addElement(new th().addElement("Active Web Stores #" + wstores.length));
|
||||
p = new p();
|
||||
for (int i = 0; i < wstores.length; i++)
|
||||
{
|
||||
MStore store = wstores[i];
|
||||
if (i > 0)
|
||||
p.addElement(" - ");
|
||||
a a = new a(store.getWebContext(), store.getName());
|
||||
a.setTarget("t" + i);
|
||||
p.addElement(a);
|
||||
}
|
||||
if (wstores.length == 0)
|
||||
p.addElement(" ");
|
||||
line.addElement(new td().addElement(p));
|
||||
table.addElement(line);
|
||||
//
|
||||
bb.addElement(table);
|
||||
} // createLogMgtPage
|
||||
|
||||
/**************************************************************************
|
||||
* Init
|
||||
* @param config config
|
||||
* @throws javax.servlet.ServletException
|
||||
*/
|
||||
public void init (ServletConfig config) throws ServletException
|
||||
{
|
||||
WebEnv.initWeb(config);
|
||||
log.info ("");
|
||||
m_serverMgr = AdempiereServerMgr.get();
|
||||
} // init
|
||||
|
||||
/**
|
||||
* Destroy
|
||||
*/
|
||||
public void destroy ()
|
||||
{
|
||||
log.info ("destroy");
|
||||
m_serverMgr = null;
|
||||
} // destroy
|
||||
|
||||
/**
|
||||
* Log error/warning
|
||||
* @param message message
|
||||
* @param e exception
|
||||
*/
|
||||
public void log (String message, Throwable e)
|
||||
{
|
||||
if (e == null)
|
||||
log.warning (message);
|
||||
log.log(Level.SEVERE, message, e);
|
||||
} // log
|
||||
|
||||
/**
|
||||
* Log debug
|
||||
* @param message message
|
||||
*/
|
||||
public void log (String message)
|
||||
{
|
||||
log.fine(message);
|
||||
} // log
|
||||
|
||||
|
||||
/**
|
||||
* Get Servlet Name
|
||||
* @return servlet name
|
||||
*/
|
||||
public String getServletName ()
|
||||
{
|
||||
return "AdempiereMonitor";
|
||||
} // getServletName
|
||||
|
||||
/**
|
||||
* Get Servlet Info
|
||||
* @return servlet info
|
||||
*/
|
||||
public String getServletInfo ()
|
||||
{
|
||||
return "Adempiere Server Monitor";
|
||||
} // getServletName
|
||||
|
||||
} // AdempiereMonitor
|
|
@ -0,0 +1,166 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.logging.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.http.*;
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
import sun.misc.*;
|
||||
|
||||
/**
|
||||
* Adempiere Monitor Filter.
|
||||
* Application Server independent check of username/password
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: AdempiereMonitorFilter.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class AdempiereMonitorFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* AdempiereMonitorFilter
|
||||
*/
|
||||
public AdempiereMonitorFilter ()
|
||||
{
|
||||
super ();
|
||||
m_authorization = new Long (System.currentTimeMillis());
|
||||
} // AdempiereMonitorFilter
|
||||
|
||||
/** Logger */
|
||||
protected CLogger log = CLogger.getCLogger(getClass());
|
||||
|
||||
/** Authorization ID */
|
||||
private static final String AUTHORIZATION = "AdempiereAuthorization";
|
||||
/** Authorization Marker */
|
||||
private Long m_authorization = null;
|
||||
|
||||
/**
|
||||
* Init
|
||||
* @param config configuration
|
||||
* @throws ServletException
|
||||
*/
|
||||
public void init (FilterConfig config)
|
||||
throws ServletException
|
||||
{
|
||||
log.info ("");
|
||||
} // Init
|
||||
|
||||
/**
|
||||
* Filter
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @param chain chain
|
||||
* @throws IOException
|
||||
* @throws ServletException
|
||||
*/
|
||||
public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
boolean error = false;
|
||||
String errorPage = "/error.html";
|
||||
boolean pass = false;
|
||||
try
|
||||
{
|
||||
if (!(request instanceof HttpServletRequest && response instanceof HttpServletResponse))
|
||||
{
|
||||
request.getRequestDispatcher(errorPage).forward(request, response);
|
||||
return;
|
||||
}
|
||||
HttpServletRequest req = (HttpServletRequest)request;
|
||||
HttpServletResponse resp = (HttpServletResponse)response;
|
||||
// Previously checked
|
||||
HttpSession session = req.getSession(true);
|
||||
Long compare = (Long)session.getAttribute(AUTHORIZATION);
|
||||
if (compare != null && compare.compareTo(m_authorization) == 0)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
else if (checkAuthorization (req.getHeader("Authorization")))
|
||||
{
|
||||
session.setAttribute(AUTHORIZATION, m_authorization);
|
||||
pass = true;
|
||||
}
|
||||
// --------------------------------------------
|
||||
if (pass)
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
resp.setHeader("WWW-Authenticate", "BASIC realm=\"Adempiere Server\"");
|
||||
}
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "filter", e);
|
||||
}
|
||||
request.getRequestDispatcher(errorPage).forward(request, response);
|
||||
} // doFilter
|
||||
|
||||
/**
|
||||
* Check Authorization
|
||||
* @param authorization authorization
|
||||
* @return true if authenticated
|
||||
*/
|
||||
private boolean checkAuthorization (String authorization)
|
||||
{
|
||||
if (authorization == null)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
String userInfo = authorization.substring(6).trim();
|
||||
BASE64Decoder decoder = new BASE64Decoder();
|
||||
String namePassword = new String (decoder.decodeBuffer(userInfo));
|
||||
// log.fine("checkAuthorization - Name:Password=" + namePassword);
|
||||
int index = namePassword.indexOf(":");
|
||||
String name = namePassword.substring(0, index);
|
||||
String password = namePassword.substring(index+1);
|
||||
MUser user = MUser.get(Env.getCtx(), name, password);
|
||||
if (user == null)
|
||||
{
|
||||
log.warning ("User not found: '" + name + "/" + password + "'");
|
||||
return false;
|
||||
}
|
||||
if (!user.isAdministrator())
|
||||
{
|
||||
log.warning ("Not a Sys Admin = " + name);
|
||||
return false;
|
||||
}
|
||||
log.info ("Name=" + name);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.log(Level.SEVERE, "check", e);
|
||||
}
|
||||
return false;
|
||||
} // check
|
||||
|
||||
/**
|
||||
* Destroy
|
||||
*/
|
||||
public void destroy ()
|
||||
{
|
||||
log.info ("");
|
||||
} // destroy
|
||||
|
||||
} // AdempiereMonitorFilter
|
|
@ -0,0 +1,96 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.web;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: ServerStatus.java,v 1.2 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class ServerStatus extends HttpServlet
|
||||
{
|
||||
/**
|
||||
* doGet
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
* @param arg0
|
||||
* @param arg1
|
||||
* @throws javax.servlet.ServletException
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
protected void doGet (HttpServletRequest arg0, HttpServletResponse arg1)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
super.doGet (arg0, arg1);
|
||||
}
|
||||
|
||||
/**
|
||||
* doPost
|
||||
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
* @param arg0
|
||||
* @param arg1
|
||||
* @throws javax.servlet.ServletException
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
protected void doPost (HttpServletRequest arg0, HttpServletResponse arg1)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
super.doPost (arg0, arg1);
|
||||
}
|
||||
|
||||
/**
|
||||
* getServletInfo
|
||||
* @see javax.servlet.Servlet#getServletInfo()
|
||||
* @return servlet info
|
||||
*/
|
||||
public String getServletInfo ()
|
||||
{
|
||||
return super.getServletInfo ();
|
||||
}
|
||||
|
||||
/**
|
||||
* init
|
||||
* @see javax.servlet.GenericServlet#init()
|
||||
* @throws javax.servlet.ServletException
|
||||
*/
|
||||
public void init ()
|
||||
throws ServletException
|
||||
{
|
||||
super.init ();
|
||||
}
|
||||
|
||||
/**
|
||||
* init
|
||||
* @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
|
||||
* @param arg0
|
||||
* @throws javax.servlet.ServletException
|
||||
*/
|
||||
public void init (ServletConfig arg0)
|
||||
throws ServletException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
super.init (arg0);
|
||||
}
|
||||
|
||||
} // ServerStatus
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.web;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.io.*;
|
||||
import javax.naming.*;
|
||||
|
||||
import javax.sql.*;
|
||||
import java.sql.*;
|
||||
|
||||
import org.compiere.interfaces.*;
|
||||
|
||||
/**
|
||||
* Status Info Servlet
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: StatusInfo.java,v 1.3 2006/07/30 00:53:33 jjanke Exp $
|
||||
*/
|
||||
public class StatusInfo extends HttpServlet
|
||||
{
|
||||
static final private String CONTENT_TYPE = "text/html";
|
||||
/**
|
||||
* Initialize global variables
|
||||
* @throws ServletException
|
||||
*/
|
||||
public void init() throws ServletException
|
||||
{
|
||||
getServletContext().log("StatusInfo.init");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get
|
||||
* @param request
|
||||
* @param response
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
response.setContentType(CONTENT_TYPE);
|
||||
PrintWriter out = response.getWriter();
|
||||
out.println("<html>");
|
||||
out.println("<head><title>Status Info</title></head>");
|
||||
out.println("<body>");
|
||||
|
||||
InitialContext context = null;
|
||||
try
|
||||
{
|
||||
context = new InitialContext();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
out.println("<p><b>" + ex + "</b></p>");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
StatusHome statusHome = (StatusHome)context.lookup (StatusHome.JNDI_NAME);
|
||||
Status status = statusHome.create();
|
||||
out.println("<p>" + status.getStatus() + "</p>");
|
||||
status.remove();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
out.println("<p><b>" + ex + "</b></p>");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ServerHome serverHome = (ServerHome)context.lookup (ServerHome.JNDI_NAME);
|
||||
Server server = serverHome.create();
|
||||
out.println("<p>" + server.getStatus() + "</p>");
|
||||
server.remove();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
out.println("<p><b>" + ex + "</b></p>");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
out.println("<h2>-- /</h2>");
|
||||
NamingEnumeration ne = context.list("/");
|
||||
while (ne.hasMore())
|
||||
out.println("<br> " + ne.nextElement());
|
||||
out.println("<h2>-- java</h2>");
|
||||
ne = context.list("java:");
|
||||
while (ne.hasMore())
|
||||
out.println("<br> " + ne.nextElement());
|
||||
out.println("<h2>-- ejb</h2>");
|
||||
ne = context.list("ejb");
|
||||
while (ne.hasMore())
|
||||
out.println("<br> " + ne.nextElement());
|
||||
|
||||
//
|
||||
|
||||
out.println("<h2>-- DS</h2>");
|
||||
DataSource ds = (DataSource)context.lookup("java:/OracleDS");
|
||||
out.println("<br> DataSource " + ds.getClass().getName() + " LoginTimeout=" + ds.getLoginTimeout());
|
||||
|
||||
Connection con = ds.getConnection("adempiere","adempiere");
|
||||
out.println("<br> Connection ");
|
||||
|
||||
getServletContext().log("Connection closed=" + con.isClosed());
|
||||
DatabaseMetaData dbmd = con.getMetaData();
|
||||
getServletContext().log("DB " + dbmd.getDatabaseProductName());
|
||||
getServletContext().log("DB V " + dbmd.getDatabaseProductVersion());
|
||||
getServletContext().log("Driver " + dbmd.getDriverName());
|
||||
getServletContext().log("Driver V " + dbmd.getDriverVersion());
|
||||
getServletContext().log("JDBC " + dbmd.getJDBCMajorVersion());
|
||||
getServletContext().log("JDBC mV " + dbmd.getJDBCMinorVersion());
|
||||
|
||||
getServletContext().log("User " + dbmd.getUserName());
|
||||
|
||||
getServletContext().log("ANSI 92 " + dbmd.supportsANSI92FullSQL());
|
||||
getServletContext().log("Connection Alter Table ADD" + dbmd.supportsAlterTableWithAddColumn());
|
||||
getServletContext().log("Connection Alter Table DROP " + dbmd.supportsAlterTableWithDropColumn());
|
||||
getServletContext().log("Connection DDL&DML " + dbmd.supportsDataDefinitionAndDataManipulationTransactions());
|
||||
getServletContext().log("Connection CatalogsIn DML " + dbmd.supportsCatalogsInDataManipulation());
|
||||
getServletContext().log("Connection Schema In DML " + dbmd.supportsSchemasInDataManipulation());
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
out.println("<p><b>" + e + "</b></p>");
|
||||
}
|
||||
|
||||
|
||||
out.println("</body></html>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Put - Processes Get
|
||||
* @param request
|
||||
* @param response
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
doGet (request, response);
|
||||
}
|
||||
/**
|
||||
* Destroy
|
||||
*/
|
||||
public void destroy()
|
||||
{
|
||||
getServletContext().log("StatusInfo.destroy");
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.3 KiB |
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- edited with XMLSPY v2004 rel. 4 U (http://www.xmlspy.com) by Jorg Janke (ComPiere, Inc.) -->
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
<display-name>Adempiere Root</display-name>
|
||||
<description>$Id: web.xml,v 1.1 2006/04/21 18:04:14 jjanke Exp $</description>
|
||||
<context-param>
|
||||
<param-name>ServerRoot</param-name>
|
||||
<param-value>1</param-value>
|
||||
</context-param>
|
||||
<filter>
|
||||
<filter-name>AdempiereMonitorFilter</filter-name>
|
||||
<display-name>Adempiere Monitor Filter</display-name>
|
||||
<filter-class>org.compiere.web.AdempiereMonitorFilter</filter-class>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>AdempiereMonitorFilter</filter-name>
|
||||
<url-pattern>/adempiereMonitor</url-pattern>
|
||||
</filter-mapping>
|
||||
<servlet>
|
||||
<servlet-name>JnlpDownloadServlet</servlet-name>
|
||||
<display-name>JNLP Download Servlet</display-name>
|
||||
<servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>logLevel</param-name>
|
||||
<param-value>INFORMATIONAL</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>StatusInfo</servlet-name>
|
||||
<display-name>Server Status</display-name>
|
||||
<description>Adempiere Server Status Info</description>
|
||||
<servlet-class>org.compiere.web.StatusInfo</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>AdempiereMonitor</servlet-name>
|
||||
<display-name>Adempiere Monitor</display-name>
|
||||
<description>Adempiere Server Monitor</description>
|
||||
<servlet-class>org.compiere.web.AdempiereMonitor</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>JnlpDownloadServlet</servlet-name>
|
||||
<url-pattern>*.jnlp</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>StatusInfo</servlet-name>
|
||||
<url-pattern>/statusInfo</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>AdempiereMonitor</servlet-name>
|
||||
<url-pattern>/adempiereMonitor/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<session-config>
|
||||
<session-timeout>15</session-timeout>
|
||||
</session-config>
|
||||
<mime-mapping>
|
||||
<extension>jar</extension>
|
||||
<mime-type>application/x-java-archive</mime-type>
|
||||
</mime-mapping>
|
||||
<mime-mapping>
|
||||
<extension>jardiff</extension>
|
||||
<mime-type>application/x-java-archive-diff</mime-type>
|
||||
</mime-mapping>
|
||||
<mime-mapping>
|
||||
<extension>jnlp</extension>
|
||||
<mime-type>application/x-java-jnlp-file</mime-type>
|
||||
</mime-mapping>
|
||||
<welcome-file-list>
|
||||
<welcome-file>adempiere.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
|
@ -0,0 +1,242 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Adempiere Application Home</title>
|
||||
|
||||
|
||||
<meta name="description" content="Adempiere Application Home">
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
<link href="standard.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
<!--
|
||||
var javawsInstalled = false;
|
||||
if (navigator.mimeTypes && navigator.mimeTypes.length)
|
||||
javawsInstalled = navigator.mimeTypes['application/x-java-jnlp-file'];
|
||||
else
|
||||
isIE = true;
|
||||
function insertLink (url, name)
|
||||
{
|
||||
if (javawsInstalled)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
document.write("You need to install Java or configure Java Web Start");
|
||||
document.write("<br>visit ");
|
||||
document.write("<a href=\"http://java.sun.com/j2se/1.5.0/download.html\">" );
|
||||
document.write("Java Installation");
|
||||
document.write("</a><br>");
|
||||
}
|
||||
}
|
||||
function MM_swapImgRestore() { //v3.0
|
||||
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
|
||||
}
|
||||
function MM_preloadImages() { //v3.0
|
||||
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
|
||||
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
|
||||
if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
|
||||
}
|
||||
function MM_findObj(n, d) { //v4.01
|
||||
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
|
||||
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
|
||||
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
|
||||
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
|
||||
if(!x && d.getElementById) x=d.getElementById(n); return x;
|
||||
}
|
||||
function MM_swapImage() { //v3.0
|
||||
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
|
||||
if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
<script language="VBScript" type="text/vbscript">
|
||||
on error resume next
|
||||
If isIE Then
|
||||
If Not(IsObject(CreateObject("JavaWebStart.IsInstalled"))) Then
|
||||
javawsInstalled = false
|
||||
Else
|
||||
javawsInstalled = true
|
||||
End If
|
||||
End If
|
||||
</script>
|
||||
</head>
|
||||
<body leftmargin="0" topmargin="0" onload="MM_preloadImages('adempiere_logo2.gif')" marginheight="0" marginwidth="0">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td background="header_banner.png" height="60">
|
||||
<table border="0" cellpadding="5" cellspacing="0" width="100%">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td align="left" valign="middle" width="477"></td>
|
||||
|
||||
<td align="left" valign="bottom"><a href="http://www.adempiere.org/"><img src="adempiere_logo.png" alt="Adempiere Logo" align="right" border="0" height="55" width="79"></a></td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td background="header_bar.jpg" height="60">
|
||||
<table border="0" cellpadding="5" cellspacing="0" width="100%">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td align="left" valign="middle"><font color="#ffffff" face="Arial, Helvetica, sans-serif" size="4">Welcome to the Adempiere 3.1.1 Home Page!<br>
|
||||
|
||||
</font></td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td height="77">
|
||||
<table id="Adempiere" border="0" cellpadding="5" cellspacing="0" width="100%">
|
||||
|
||||
<!--DWLayoutTable-->
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5" valign="top" width="23%">
|
||||
<h2>
|
||||
<font color="#000000">Web Start</font>
|
||||
</h2>
|
||||
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1" width="77%">
|
||||
<p>
|
||||
<a href="adempiere.jnlp">
|
||||
<img src="webstart.jpg" alt="Adempiere WebStart" align="right" border="0" height="57" width="237">
|
||||
</a>
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
<!--
|
||||
insertLink ("adempiere.jnlp","Adempiere Web Start");
|
||||
// -->
|
||||
</script>
|
||||
Install <a href="http://java.sun.com/j2se/1.5.0/download.html" target="sun">Java 1.5.0 JRE (Runtime)</a>
|
||||
and press WebStart<br>
|
||||
|
||||
Check also WebStart <a href="http://www.adempiere.org/support/install/webStart.html" target="c">Details</a>.<br>
|
||||
|
||||
If you have trouble starting, try <a href="/admin/adempiereHome/adempiereDirect.jnlp">this</a>
|
||||
(or via <a href="/admin/applet.html">Applet</a>)
|
||||
</p>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5">
|
||||
<h2><font color="#000000">Local Install </font></h2>
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1"><a href="/admin/adempiereHome/AdempiereClient.zip"><img src="zip.gif" alt="Adempiere Client Zip" align="right" border="0" height="32" width="32"></a>Install <a href="http://java.sun.com/j2se/1.5.0/download.html" target="sun">Java 1.5.0 JRE (Runtime)</a>; Download and extract the Adempiere Client <a href="/admin/adempiereHome/AdempiereClient.zip" title="Download Adempiere Client">zip</a> file on your Client;. <br>
|
||||
|
||||
Start Adempiere via RUN_Adempiere </td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5" valign="top">
|
||||
<h2><font color="#000000">Web Application</font></h2>
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1">
|
||||
<p><a href="/adempiere">Adempiere Web Application Login (</a><a href="/adempiere/WStart">alternative)</a></p>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5" valign="top">
|
||||
<h2><font color="#000000">Self Service</font></h2>
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1"><a href="/wstore/index.jsp">Web Store</a> - Send <a href="/wstore/request.jsp">Request</a></td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5" valign="top">
|
||||
<h2><font color="#000000">Server Admin</font></h2>
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1">
|
||||
<p><a href="/admin/adempiereMonitor">Adempiere Server Managment</a>
|
||||
<!--a href="/jmx-console" target="_blank">JBoss 3.2.3 Management Server Agent</a -->
|
||||
</p>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td bgcolor="#e9eef5" valign="top">
|
||||
<h2><font color="#000000">Adempiere Support</font></h2>
|
||||
</td>
|
||||
|
||||
<td bgcolor="#fbf8f1">
|
||||
<p><a href="http://www.adempiere.com/wiki/">Wiki</a> - <a href="http://www.adempiere.com/wiki/index.php/Manual">Manual</a> - <a href="irc://irc.freenode.net/adempiere">IRC Channel</a><br>
|
||||
|
||||
<a href="http://sourceforge.net/forum/?group_id=176962">Forums</a> - <a href="http://sourceforge.net/tracker/?group_id=176962&atid=879333">Support Requests</a></p>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td background="footer_bar.gif" height="55">
|
||||
<table border="0" cellpadding="5" cellspacing="0" width="100%">
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td>© Copyright 2006 Adempiere - All rights reserved - <a href="http://www.gnu.org/licenses/gpl.html" target="_blank">Adempiere License is GPL</a></td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h1> </h1>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version = "1.0" encoding = "UTF-8"?>
|
||||
<jnlp spec = "1.5+" version = "2.5.3"
|
||||
codebase = "$$context/adempiereHome"
|
||||
href = "$$context/adempiere.jnlp">
|
||||
<information>
|
||||
<title>Adempiere Client 3.1.1 $$context</title>
|
||||
<vendor>ComPiere, Inc.</vendor>
|
||||
<homepage href = "http://www.adempiere.org"/>
|
||||
<offline-allowed/>
|
||||
<description>Adempiere ERP+CRM ($$context) - Smart Business Solution for Distribution and Service - globally</description>
|
||||
<description kind = "short">Adempiere ERP+CRM ($$context)</description>
|
||||
<description kind = "one-line">Adempiere ERP+CRM</description>
|
||||
<description kind = "tooltip">Adempiere ERP+CRM ($$context)</description>
|
||||
<icon href = "$$context/C32.gif"/>
|
||||
<shortcut online="true">
|
||||
<desktop/>
|
||||
<menu submenu="Adempiere 3.1.1 $$context"/>
|
||||
</shortcut>
|
||||
</information>
|
||||
<resources>
|
||||
<j2se version = "1.5+" href = "http://java.sun.com/products/autodl/j2se" initial-heap-size = "32m" max-heap-size = "512m"/>
|
||||
<jar href = "Adempiere.jar" main = "true" download = "eager"/>
|
||||
<jar href = "AdempiereCLib.jar" main = "false" download = "eager"/>
|
||||
<property name="adempiereJNLP" value="$$context"/>
|
||||
</resources>
|
||||
<application-desc main-class = "org.compiere.Adempiere"/>
|
||||
<security>
|
||||
<all-permissions/>
|
||||
</security>
|
||||
</jnlp>
|
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 5.6 KiB |
|
@ -0,0 +1,81 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Adempiere Client Applet Start</title>
|
||||
<link href="standard.css" rel="stylesheet" type="text/css" />
|
||||
<style type="text/css">
|
||||
<!--
|
||||
.warning {
|
||||
color: #FF0000;
|
||||
font-weight: bold;
|
||||
}
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Adempiere Client Applet Start</h1>
|
||||
<p> Due to Browser incompatibilities, here is a list of different ways to start the Adempiere Java Client from a Browser.
|
||||
This requires that your browser supports Java. <br/>
|
||||
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/plugin/developer_guide/using_tags.html" target="_blank">Applet Start Details</a>
|
||||
</p>
|
||||
<p class="warning">After the Adempiere Client started DO NOT close/use this window as that will crash the application!</p>
|
||||
<table width="*" border="1" cellspacing="5" cellpadding="5">
|
||||
<tr>
|
||||
<td> Microsoft IE <br />
|
||||
<object classid="clsid:CAFEEFAC-0014-0002-0000-ABCDEFFEDCBA"
|
||||
width="200" height="100"
|
||||
codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0">
|
||||
<param name="code" value="org/adempiere/apps/AApplet.class" />
|
||||
<param name="codebase" value="/admin/adempiereHome/" />
|
||||
<param name="archive" value="Adempiere.jar,AdempiereCLib.jar"/>
|
||||
<param name="type" value="application/x-java-applet;jpi-version=1.5.0" />
|
||||
Internet Explorer: No Java 2 SDK, Standard Edition v 1.5.0 support for APPLET
|
||||
</object>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><!--[if !IE]> -->
|
||||
Non IE Browsers <br />
|
||||
<object classid="java:org/adempiere/apps/AApplet.class"
|
||||
archive="Adempiere.jar,AdempiereCLib.jar"
|
||||
codebase="/admin/adempiereHome/"
|
||||
width="200" height="100">
|
||||
</object>
|
||||
<!-- <![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Browsers supporting the EMBED tag <br />
|
||||
Code commented out - modify source if required! <br />
|
||||
<!-- start (add the < before the tag) --
|
||||
embed type="application/x-java-applet;jpi-version=1.5.0"
|
||||
width="200" height="100"
|
||||
code="org/adempiere/apps/AApplet.class"
|
||||
codebase="/admin/adempiereHome/"
|
||||
archive="Adempiere.jar AdempiereCLib.jar"
|
||||
pluginspage="http://java.sun.com/j2se/1.5/download.html">
|
||||
<noembed>
|
||||
Browsers supporting the EMBED tag: No Java 2 SDK, Standard Edition v 1.5.0 support for APPLET
|
||||
</noembed>
|
||||
</embed>
|
||||
<!-- end -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Browsers supporting the APPLET tag <br />
|
||||
Code commented out - modify source if required! <br />
|
||||
<!-- start (add the < before the tag) --
|
||||
applet code="org/adempiere/apps/AApplet.class"
|
||||
archive="Adempiere.jar,AdempiereCLib.jar"
|
||||
codebase="/admin/adempiereHome/"
|
||||
width="200" height="200">
|
||||
Browsers supporting the APPLET tag: No Java 2 SDK, Standard Edition v 1.5.0 support for APPLET
|
||||
</applet>
|
||||
<!-- end -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Adempiere Server Error</title>
|
||||
<link href="/standard.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Adempiere Server Error </h1>
|
||||
<p>The Adempiere Server encountered a unrecoverable error.</p>
|
||||
<h2>Please notify the administrator.</h2>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 6.6 KiB |
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Adempiere</title>
|
||||
<meta name="description" content="Adempiere Root Page">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
document.location='adempiere.html';
|
||||
</script>
|
||||
<p>Click <a href="adempiere.html">here</a> if not forwarded automatically</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
||||
Disallow: /adempiere
|
||||
Disallow: /jmx-console
|
|
@ -0,0 +1,151 @@
|
|||
/* Adempiere Root (c) Jorg Janke */
|
||||
/* $Id: standard.css,v 1.1 2006/04/21 18:04:14 jjanke Exp $ */
|
||||
body{
|
||||
background-color: #FFFFFF;
|
||||
color: #000000;
|
||||
font-size: 76%;
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
a{
|
||||
color: #3465a4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1{
|
||||
color: #FF0000;
|
||||
font-size: x-large;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h2{
|
||||
color: #000066;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
h3{
|
||||
color: #0000CC;
|
||||
font-size: medium;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4{
|
||||
color: #6600CC;
|
||||
font-size: medium;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h5{
|
||||
color: #660099;
|
||||
font-size: medium;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h6{
|
||||
font-size: larger;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
hr{
|
||||
color: #000099;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
p{
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
th{
|
||||
background-color: #E6E6FA;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
caption{
|
||||
color: #660099;
|
||||
text-align: left;
|
||||
font-style: italic;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
|
||||
.menuDetail{
|
||||
color: #660099;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 12px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 20px;
|
||||
padding-top: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menuDetail:hover{
|
||||
color: #660099;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 12px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 20px;
|
||||
padding-top: 0;
|
||||
text-decoration: none;
|
||||
background-color: #99FFFF;
|
||||
}
|
||||
|
||||
.menuMain{
|
||||
color: #000066;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menuMain:hover{
|
||||
color: #000066;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
background-color: #99FFFF;
|
||||
}
|
||||
|
||||
.menuSub{
|
||||
color: #000066;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 14px;
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menuSub:hover{
|
||||
color: #000066;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 14px;
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
background-color: #99FFFF;
|
||||
}
|
||||
|
||||
.Cerror{
|
||||
background:#FF4A4A;
|
||||
}
|
||||
.Cmandatory{
|
||||
background:#9DFFFF;
|
||||
}
|
||||
.Cbasket{
|
||||
font-size: 9px;
|
||||
display: inline;
|
||||
}
|
||||
#imgButton{
|
||||
border-style:outset;
|
||||
}
|
||||
#imgButtonPressed{
|
||||
border-style:inset;
|
||||
}
|
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project default="_generation_" name="XDoclet Generator">
|
||||
<path id="xdoclet.classpath"><pathelement location="C:/Adempiere/adempiere-all2/serverRoot/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/serverRoot/src/web/WEB-INF/lib/jnlp-servlet.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/looks/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/local"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/jstl.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/log4j.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/Verisign.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/saxpath.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/bsh-core-1.2b3.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/xdoclet.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/mail.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/activation.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/standard.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/tools/lib/ocrs12.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/dbPort/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/jboss/client/jbossall-client.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/jboss/server/adempiere/lib/javax.servlet.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/jboss/lib/jboss-jmx.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/jboss/lib/jboss-system.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/lib/oracle.jar"/>
|
||||
<pathelement location="C:/eclipse/plugins/org.junit_3.8.1/junit.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/interfaces/Interfaces.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/lib/postgresql.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/server/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/base/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/print/lib"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/lib/jPDFPrinterDemo.jar"/>
|
||||
<pathelement location="C:/Adempiere/adempiere-all2/interfaces/classes"/>
|
||||
|
||||
<fileset dir="C:/eclipse/plugins/org.jboss.ide.eclipse.xdoclet.core_1.2.130/">
|
||||
<include name="*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<target name="_generation_" depends=""/>
|
||||
</project>
|