📄 doc.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Business Solution
* The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
* Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
* created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.acct;
import java.sql.*;
import java.math.*;
import java.util.*;
import org.apache.log4j.*;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.model.*;
/**
* Posting Document Root.
*
* <pre>
* Table Base Document Types (C_DocType.DocBaseType & AD_Reference_ID=183)
* Class AD_Table_ID
* ------------------ ------------------------------
* C_Invoice: ARI, ARC, ARF, API, APC
* Doc_Invoice 318 - has C_DocType_ID
*
* C_Payment: ARP, APP
* Doc_Payment 335 - has C_DocType_ID
*
* C_Order: SOO, POO, POR (Requisition)
* Doc_Order 259 - has C_DocType_ID
*
* M_InOut: MMS, MMR
* Doc_InOut 319 - DocType derived
*
* M_Inventory: MMI
* Doc_Inventory 321 - DocType fixed
*
* M_Movement: MMM
* Doc_Movement 323 - DocType fixed
*
* M_Production: MMP
* Doc_Production 325 - DocType fixed
*
* C_BankStatement: CMB
* Doc_Bank 392 - DocType fixed
*
* C_Cash: CMC
* Doc_Cash 407 - DocType fixed
*
* C_Allocation: CMA
* Doc_Allocation 390 - DocType fixed
*
* GL_Journal: GLJ
* Doc_GLJournal 224 = has C_DocType_ID
*
* Matching Invoice MXI
* M_MatchInv 472 - DocType fixed
*
* Matching PO MXP
* M_MatchPO 473 - DocType fixed
*
* </pre>
* @author Jorg Janke
* @version $Id: Doc.java,v 1.24 2003/03/21 02:38:46 jjanke Exp $
*/
public abstract class Doc
{
/** AD_Table_ID's of documents */
protected static int[] documents = new int[] {
318, // C_Invoice
390, // C_Allocation
407, // C_Cash
392, // C_BankStatement
259, // C_Order
335, // C_Payment
319, // M_InOut
321, // M_Inventory
323, // M_Movement
325, // M_Production
224, // GL_Journal
472, // M_MatchInv
473 // M_MatchPO
};
/**
* Factory - Create Posting document
*
* @param AD_Table_ID Table ID of Documents
* @param AD_Client_ID Client ID of Documents
* @return Document
*/
protected static Doc get (int AD_Table_ID, int AD_Client_ID)
{
Doc doc = null;
switch (AD_Table_ID)
{
case 318:
doc = new Doc_Invoice (AD_Client_ID);
break;
case 390:
doc = new Doc_Allocation (AD_Client_ID);
break;
case 407:
doc = new Doc_Cash (AD_Client_ID);
break;
case 392:
doc = new Doc_Bank (AD_Client_ID);
break;
case 259:
doc = new Doc_Order (AD_Client_ID);
break;
case 335:
doc = new Doc_Payment (AD_Client_ID);
break;
case 319:
doc = new Doc_InOut (AD_Client_ID);
break;
case 321:
doc = new Doc_Inventory (AD_Client_ID);
break;
case 323:
doc = new Doc_Movement (AD_Client_ID);
break;
case 325:
doc = new Doc_Production (AD_Client_ID);
break;
case 224:
doc = new Doc_GLJournal (AD_Client_ID);
break;
case 472:
doc = new Doc_MatchInv (AD_Client_ID);
break;
case 473:
doc = new Doc_MatchPO (AD_Client_ID);
break;
}
if (doc == null)
s_log.error("get - Unknown AD_Table_ID=" + AD_Table_ID);
return doc;
} // get
/**
* Post Document
*
* @param AD_Table_ID Table ID of Document
* @param AD_Client_ID Client ID of Document
* @param Record_ID Record ID of this document
* @param force force posting
* @return true if the document was posted
*/
protected static boolean post (int AD_Table_ID, int AD_Client_ID, int Record_ID, boolean force)
{
Doc doc = get (AD_Table_ID, AD_Client_ID);
if (doc != null)
return doc.post (Record_ID, force);
return false;
} // post
/** Connection for commits */
private static Connection s_connection = null;
/** Log */
protected Logger log = Logger.getLogger(getClass());
protected static Logger s_log = Logger.getLogger(Doc.class);
/**
* Return Serialized Connection for Commits (not AutoCommit)
* @return connection for posting
*/
private static Connection getConnection ()
{
if (s_connection != null)
{
try
{
if (!s_connection.isClosed())
return s_connection;
}
catch (SQLException e)
{
s_log.error("getConnection", e);
}
}
s_connection = DB.createConnection(false, Connection.TRANSACTION_SERIALIZABLE);
return s_connection;
} // getConnection
/*************************************************************************/
/**
* Cosntructor
* @param AD_Client_ID Client ID of these Documents
*/
Doc (int AD_Client_ID)
{
log.info(getTableName() + ", Client=" + AD_Client_ID);
m_AD_Client_ID = AD_Client_ID;
m_as = AcctSchema.getAcctSchemaArray (AD_Client_ID);
} // Doc
/** Client for data access - there is also a document Client_ID (which should be the same) */
private int m_AD_Client_ID;
/** Accounting Schema Array */
private AcctSchema[] m_as = null;
/** Facts */
private Fact[] m_fact = null;
/** No Currency in Document Indicator */
protected static final int NO_CURRENCY = -1;
/** Document Value Object */
protected DocVO p_vo = null;
/** Contained Doc Lines */
protected DocLine[] p_lines = new DocLine[0];
/**
* Post Document.
* <pre>
* - try to lock document (Processed='Y' (AND Processing='N' AND Posted='N'))
* - if not ok - return false
* - read ResultSet
* - postlogic (for all Accounting Schema)
* - create Fact lines
* - postCommit
* - commits Fact lines and Document & sets Processing = 'N'
* - if error - create Note
* </pre>
* @param Record_ID ID of the record in the table
* @param force - if true, repost (ignore if already posted or locked)
* @return true if posted
*/
public final boolean post (int Record_ID, boolean force)
{
boolean retValue = false;
// Lock Record ----
StringBuffer sql = new StringBuffer ("UPDATE ");
sql.append(getTableName()).append( " SET Processing='Y' WHERE ")
.append(getTableName()).append("_ID=").append(Record_ID)
.append(" AND Processed='Y'");
if (!force)
sql.append(" AND (Processing='N' OR Processing IS NULL) AND Posted='N'");
if (DB.executeUpdate(sql.toString()) != 1)
{
log.error("post - Cannot lock Document - ignored: " + getTableName() + "_ID=" + Record_ID);
return false;
}
// Get Record Info ----
sql = new StringBuffer ("SELECT * FROM ");
sql.append(getTableName())
.append(" WHERE AD_Client_ID=? AND ") // additional security
.append(getTableName()).append("_ID=?");
try
{
PreparedStatement pstmt = DB.prepareStatement(sql.toString());
pstmt.setInt(1, m_AD_Client_ID);
pstmt.setInt(2, Record_ID);
ResultSet rs = pstmt.executeQuery();
if (rs.next())
retValue = post (rs, force); // ----
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.error("post", e);
retValue = false;
}
return retValue;
} // post
/*************************************************************************/
/**
* Post current Document in ResultSet.
* - Create Fact per Accounting Schema
* - Load Document
* - Post Commit
*
* @param rs Resultset with one row (SELECT * FROM documentTable)
* @param force if true delete existing accounting
* @return true if posted
*/
private final boolean post (ResultSet rs, boolean force)
{
// log.info("post");
if (!loadDocument (rs, force))
return false;
// Create Fact per AcctSchema
m_fact = new Fact [m_as.length];
// for all Accounting Schema
boolean OK = true;
for (int i = 0; OK && i < m_as.length; i++)
{
p_vo.Status = postLogic (i);
if (!p_vo.Status.equals(DocVO.STATUS_Posted))
OK = false;
}
// commitFact
p_vo.Status = postCommit (p_vo.Status);
// Create Note
if (!p_vo.Status.equals(DocVO.STATUS_Posted))
{
// Insert Note
String AD_Message = "PostingError-" + p_vo.Status;
// Refernce - Document
String Reference = toString();
// Reference
String cn = getClass().getName();
StringBuffer Text = new StringBuffer (Msg.getMsg(Env.getCtx(), AD_Message));
if (p_vo.Error != null)
Text.append(" (").append(p_vo.Error).append(")");
Text.append(" - ").append(cn.substring(cn.lastIndexOf('.')))
.append(" (").append(p_vo.DocumentType)
.append(" - DocumentNo=").append(p_vo.DocumentNo)
.append(", DateAcct=").append(p_vo.DateAcct.toString().substring(0,10))
.append(", Amount=").append(getAmount())
.append(", Sta=").append(p_vo.Status)
.append(" - PeriodOpen=").append(isPeriodOpen())
.append(", Balanced=").append(isBalanced());
int AD_User_ID = 0;
DB.insertNote(p_vo.AD_Client_ID, p_vo.AD_Org_ID, AD_User_ID,
getAD_Table_ID(), p_vo.Record_ID, AD_Message, Reference, Text.toString());
}
// dispose facts
for (int i = 0; i < m_fact.length; i++)
if (m_fact[i] != null)
m_fact[i].dispose();
p_lines = null;
return p_vo.Status.equals(DocVO.STATUS_Posted);
} // post
/**
* Posting logic for Accounting Schema index
* @param index Accounting Schema index
* @return posting status/error code
*/
private final String postLogic (int index)
{
// rejectUnbalanced
if (!m_as[index].isSuspenseBalancing() && !isBalanced())
return DocVO.STATUS_NotBalanced;
// rejectUnconvertible
if (!isConvertible(m_as[index]))
return DocVO.STATUS_NotConvertible;
// rejectPeriodClosed
if (!isPeriodOpen())
return DocVO.STATUS_PeriodClosed;
// createFacts
m_fact[index] = createFact (m_as[index]);
if (m_fact[index] == null)
return DocVO.STATUS_Error;
p_vo.Status = DocVO.STATUS_PostPrepared;
// balanceSource
if (!m_fact[index].isSourceBalanced())
m_fact[index].balanceSource();
// balanceSegments
if (!m_fact[index].isSegmentBalanced())
m_fact[index].balanceSegments();
// balanceAccounting
if (!m_fact[index].isAcctBalanced())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -