/****************************************************************************** * 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 * *****************************************************************************/ /** * 2007, Modified by Posterita Ltd. */ package org.adempiere.webui.acct; import static org.compiere.model.SystemIDs.REFERENCE_POSTING_TYPE; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import java.util.logging.Level; import org.adempiere.webui.component.Listbox; import org.compiere.model.MAcctSchema; import org.compiere.model.MAcctSchemaElement; import org.compiere.model.MFactAcct; import org.compiere.model.MJournal; import org.compiere.model.MLookupFactory; import org.compiere.model.MRefList; import org.compiere.model.SystemIDs; import org.compiere.report.core.RColumn; import org.compiere.report.core.RModel; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.ValueNamePair; /** * State and data access helper for {@link WAcctViewer} * * @author Niraj Sohun * July 27, 2007 */ public class WAcctViewerData { /** Window */ public int WindowNo; /** Client */ public int AD_Client_ID; /** All Accounting Schemas for client */ public MAcctSchema[] ASchemas = null; /** Selected Accounting Schema */ public MAcctSchema ASchema = null; // Selection Info /** Document Query - query with {@link #AD_Table_ID} and {@link #Record_ID} */ public boolean documentQuery = false; /** Selected Accounting Schema ID */ public int C_AcctSchema_ID = 0; /** Selected Posting Type */ public String PostingType = ""; /** Selected Organization ID */ public int AD_Org_ID = 0; /** Date From, for DateAcct filter */ public Timestamp DateFrom = null; /** Date To, for DateAcct filter */ public Timestamp DateTo = null; // Document Table Selection Info /** Selected Table ID for {@link #documentQuery} */ public int AD_Table_ID; /** Selected Record ID for {@link #documentQuery} */ public int Record_ID; /** ColumnName:Filter */ public HashMap whereInfo = new HashMap(); /** TableName:AD_Table_ID */ public HashMap tableInfo = new HashMap(); // Display Info /** Display Qty Columns */ protected boolean displayQty = false; /** Display Source Amount Columns */ protected boolean displaySourceAmt = false; /** Display Document info */ protected boolean displayDocumentInfo = false; //order by protected String sortBy1 = ""; protected String sortBy2 = ""; protected String sortBy3 = ""; protected String sortBy4 = ""; //group by protected boolean group1 = false; protected boolean group2 = false; protected boolean group3 = false; protected boolean group4 = false; /** Leading Columns. Number of columns shown before Accounted and Source Amount Columns. */ private int m_leadingColumns = 0; /** UserElement1 Reference */ private String m_ref1 = null; /** UserElement2 Reference */ private String m_ref2 = null; /** Logger */ private static final CLogger log = CLogger.getCLogger(WAcctViewerData.class); /** * Constructor * @param ctx context * @param windowNo window no * @param ad_Client_ID client * @param ad_Table_ID table */ public WAcctViewerData (Properties ctx, int windowNo, int ad_Client_ID, int ad_Table_ID) { WindowNo = windowNo; AD_Client_ID = ad_Client_ID; if (AD_Client_ID == 0) AD_Client_ID = Env.getContextAsInt(Env.getCtx(), WindowNo, "AD_Client_ID"); if (AD_Client_ID == 0) AD_Client_ID = Env.getContextAsInt(Env.getCtx(), "AD_Client_ID"); AD_Table_ID = ad_Table_ID; ASchemas = MAcctSchema.getClientAcctSchema(ctx, AD_Client_ID); ASchema = ASchemas[0]; } // AcctViewerData /** * Dispose */ public void dispose() { ASchemas = null; ASchema = null; whereInfo.clear(); whereInfo = null; Env.clearWinContext(WindowNo); } // dispose /** * GL Journal only posts in one Accounting Schema. * If the record is a GL Journal, remove the other accounting schema from {@link #ASchemas} * @param Record_ID */ protected void validateAcctSchemas(int Record_ID) { if (Record_ID > 0 && AD_Table_ID == MJournal.Table_ID) { MJournal journal = new MJournal(Env.getCtx(), Record_ID, null); if (journal.getGL_Journal_ID() == Record_ID) { ASchemas = new MAcctSchema[1]; ASchemas[0] = MAcctSchema.get(Env.getCtx(), journal.getC_AcctSchema_ID()); ASchema = ASchemas[0]; } } } // validateAcctSchemas /** * Fill Accounting Schema * @param cb Listbox to be filled */ protected void fillAcctSchema (Listbox cb) { for (int i = 0; i < ASchemas.length; i++) { KeyNamePair key = new KeyNamePair(ASchemas[i].getC_AcctSchema_ID(), ASchemas[i].getName()); cb.appendItem(key.getName(), key); } } // fillAcctSchema /** * Fill Posting Type from {@link SystemIDs#REFERENCE_POSTING_TYPE} list. * @param cb Listbox to be filled */ protected void fillPostingType (Listbox cb) { int AD_Reference_ID = REFERENCE_POSTING_TYPE; ValueNamePair[] pt = MRefList.getList(Env.getCtx(), AD_Reference_ID, true); for (int i = 0; i < pt.length; i++) { cb.appendItem(pt[i].getName(), pt[i]); } } // fillPostingType /** * Fill Listbox with * ValueNamePair (TableName, translatedKeyColumnName) * and {@link #tableInfo} with (TableName, AD_Table_ID) * and select the entry for AD_Table_ID * * @param cb Listbox to be filled */ protected void fillTable (Listbox cb) { String sql = "SELECT AD_Table_ID, TableName FROM AD_Table t " + "WHERE EXISTS (SELECT * FROM AD_Column c" + " WHERE t.AD_Table_ID=c.AD_Table_ID AND c.ColumnName='Posted')" + " AND IsView='N'"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); rs = pstmt.executeQuery(); while (rs.next()) { int id = rs.getInt(1); String tableName = rs.getString(2); String name = Msg.translate(Env.getCtx(), tableName+"_ID"); ValueNamePair pp = new ValueNamePair(tableName, name); cb.appendItem(pp.getName(),pp); tableInfo.put (tableName, Integer.valueOf(id)); } } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } } // fillTable /** * Fill Org * * @param cb Listbox to be filled */ protected void fillOrg (Listbox cb) { KeyNamePair pp = new KeyNamePair(0, ""); cb.appendItem(pp.getName(), pp); String sql = "SELECT AD_Org_ID, Name FROM AD_Org WHERE AD_Client_ID=? ORDER BY Value"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, AD_Client_ID); rs = pstmt.executeQuery(); while (rs.next()) { KeyNamePair key = new KeyNamePair(rs.getInt(1), rs.getString(2)); cb.appendItem(key.getName(), key); } } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } } // fillOrg /** * Get Info Button Text * * @param tableName table * @param columnName column * @param selectSQL sql * @return Text on button */ protected String getButtonText (String tableName, String columnName, String selectSQL) { // SELECT () FROM tableName avd WHERE avd. StringBuilder sql = new StringBuilder ("SELECT ("); Language language = Env.getLanguage(Env.getCtx()); sql.append(MLookupFactory.getLookup_TableDirEmbed(language, columnName, "avd")) .append(") FROM ").append(tableName).append(" avd WHERE avd.").append(selectSQL); String retValue = "<" + selectSQL + ">"; Statement stmt = null; ResultSet rs = null; try { stmt = DB.createStatement(); rs = stmt.executeQuery(sql.toString()); if (rs.next()) retValue = rs.getString(1); } catch (SQLException e) { log.log(Level.SEVERE, sql.toString(), e); } finally { DB.close(rs, stmt); rs = null; stmt = null; } return retValue; } // getButtonText /** * Create query and execute * @return {@link RModel} query result */ protected RModel query() { // Set Where Clause StringBuilder whereClause = new StringBuilder(); // Add Organization if (C_AcctSchema_ID != 0) whereClause.append(RModel.TABLE_ALIAS).append(".C_AcctSchema_ID=").append(C_AcctSchema_ID); // Posting Type Selected if (PostingType != null && PostingType.length() > 0) { if (whereClause.length() > 0) whereClause.append(" AND "); whereClause.append(RModel.TABLE_ALIAS) .append(".PostingType='").append(PostingType).append("'"); } if (documentQuery) { if (whereClause.length() > 0) whereClause.append(" AND "); whereClause.append(RModel.TABLE_ALIAS).append(".AD_Table_ID=").append(AD_Table_ID) .append(" AND ").append(RModel.TABLE_ALIAS).append(".Record_ID=").append(Record_ID); } else { // get values (Queries) Iterator it = whereInfo.values().iterator(); while (it.hasNext()) { String where = it.next(); if (where != null && where.length() > 0) // add only if not empty { if (whereClause.length() > 0) whereClause.append(" AND "); whereClause.append(RModel.TABLE_ALIAS).append(".").append(where); } } if (DateFrom != null || DateTo != null) { if (whereClause.length() > 0) whereClause.append(" AND "); if (DateFrom != null && DateTo != null) whereClause.append("TRUNC(").append(RModel.TABLE_ALIAS).append(".DateAcct) BETWEEN ") .append(DB.TO_DATE(DateFrom)).append(" AND ").append(DB.TO_DATE(DateTo)); else if (DateFrom != null) whereClause.append("TRUNC(").append(RModel.TABLE_ALIAS).append(".DateAcct) >= ") .append(DB.TO_DATE(DateFrom)); else // DateTo != null whereClause.append("TRUNC(").append(RModel.TABLE_ALIAS).append(".DateAcct) <= ") .append(DB.TO_DATE(DateTo)); } // Add Organization if (AD_Org_ID != 0) { if (whereClause.length() > 0) whereClause.append(" AND "); whereClause.append(RModel.TABLE_ALIAS).append(".AD_Org_ID=").append(AD_Org_ID); } } // Set Order By Clause StringBuilder orderClause = new StringBuilder(); if (sortBy1.length() > 0) orderClause.append(RModel.TABLE_ALIAS).append(".").append(sortBy1); if (sortBy2.length() > 0) { if (orderClause.length() > 0) orderClause.append(","); orderClause.append(RModel.TABLE_ALIAS).append(".").append(sortBy2); } if (sortBy3.length() > 0) { if (orderClause.length() > 0) orderClause.append(","); orderClause.append(RModel.TABLE_ALIAS).append(".").append(sortBy3); } if (sortBy4.length() > 0) { if (orderClause.length() > 0) orderClause.append(","); orderClause.append(RModel.TABLE_ALIAS).append(".").append(sortBy4); } if (orderClause.length() == 0) orderClause.append(RModel.TABLE_ALIAS).append(".Fact_Acct_ID"); RModel rm = getRModel(); // Groups if ((group1 || group2 || group3 || group4) && sortBy1.length() > 0) rm.setGroup(sortBy1); if ((group2 || group3 || group4) && sortBy2.length() > 0) rm.setGroup(sortBy2); if ((group3 || group4) && sortBy3.length() > 0) rm.setGroup(sortBy3); if (group4 && sortBy4.length() > 0) rm.setGroup(sortBy4); // Totals rm.setFunction("AmtAcctDr", RModel.FUNCTION_SUM); rm.setFunction("AmtAcctCr", RModel.FUNCTION_SUM); rm.query (Env.getCtx(), whereClause.toString(), orderClause.toString()); return rm; } // query /** * Create new Report Model (Setup Columns) instance * @return {@link RModel} */ private RModel getRModel() { Properties ctx = Env.getCtx(); RModel rm = new RModel("Fact_Acct"); // Add Key (Lookups) ArrayList keys = createKeyColumns(); int max = m_leadingColumns; if (max == 0) max = keys.size(); for (int i = 0; i < max; i++) { String column = keys.get(i); if (column != null && column.startsWith("Date")) rm.addColumn(new RColumn(ctx, column, DisplayType.Date)); else if (column != null && column.endsWith("_ID")) rm.addColumn(new RColumn(ctx, column, DisplayType.TableDir)); } // Main Info rm.addColumn(new RColumn(ctx, "AmtAcctDr", DisplayType.Amount)); rm.addColumn(new RColumn(ctx, "AmtAcctCr", DisplayType.Amount)); if (displaySourceAmt) { if (!keys.contains("DateTrx")) rm.addColumn(new RColumn(ctx, "DateTrx", DisplayType.Date)); rm.addColumn(new RColumn(ctx, "C_Currency_ID", DisplayType.TableDir)); rm.addColumn(new RColumn(ctx, "AmtSourceDr", DisplayType.Amount)); rm.addColumn(new RColumn(ctx, "AmtSourceCr", DisplayType.Amount)); rm.addColumn(new RColumn(ctx, "Rate", DisplayType.Amount, "CASE WHEN (AmtSourceDr + AmtSourceCr) = 0 THEN 0" + " ELSE (AmtAcctDr + AmtAcctCr) / (AmtSourceDr + AmtSourceCr) END")); } // Remaining Keys for (int i = max; i < keys.size(); i++) { String column = keys.get(i); if (column != null && column.startsWith("Date")) rm.addColumn(new RColumn(ctx, column, DisplayType.Date)); else if (column!=null && column.startsWith("UserElement")) { if (column.indexOf('1') != -1) rm.addColumn(new RColumn(ctx, column, DisplayType.TableDir, null, 0, m_ref1)); else rm.addColumn(new RColumn(ctx, column, DisplayType.TableDir, null, 0, m_ref2)); } else if (column != null && column.endsWith("_ID")) rm.addColumn(new RColumn(ctx, column, DisplayType.TableDir)); } // Info if (!keys.contains("DateAcct")) rm.addColumn(new RColumn(ctx, "DateAcct", DisplayType.Date)); if (!keys.contains("C_Period_ID")) rm.addColumn(new RColumn(ctx, "C_Period_ID", DisplayType.TableDir)); if (displayQty) { rm.addColumn(new RColumn(ctx, "C_UOM_ID", DisplayType.TableDir)); rm.addColumn(new RColumn(ctx, "Qty", DisplayType.Quantity)); } rm.addColumn(new RColumn(ctx, "AD_Table_ID", DisplayType.TableDir)); rm.addColumn(new RColumn(ctx, "Record_ID", DisplayType.ID)); rm.addColumn(new RColumn(ctx, "Fact_Acct_ID", DisplayType.ID)); if (displayDocumentInfo) { rm.addColumn(new RColumn(ctx, "Description", DisplayType.String)); } if (PostingType == null || PostingType.length() == 0) rm.addColumn(new RColumn(ctx, "PostingType", DisplayType.List, // teo_sarca, [ 1664208 ] RModel.TABLE_ALIAS+".PostingType", MFactAcct.POSTINGTYPE_AD_Reference_ID, null)); return rm; } // createRModel /** * Create the list of key/mandatory columns to display in viewer * @return List of Key Columns */ private ArrayList createKeyColumns() { ArrayList columns = new ArrayList(); m_leadingColumns = 0; // Sorting Fields columns.add(sortBy1); // may add "" if (!columns.contains(sortBy2)) columns.add(sortBy2); if (!columns.contains(sortBy3)) columns.add(sortBy3); if (!columns.contains(sortBy4)) columns.add(sortBy4); // Add Account Segments MAcctSchemaElement[] elements = ASchema.getAcctSchemaElements(); for (int i = 0; i < elements.length; i++) { if (m_leadingColumns == 0 && columns.contains("AD_Org_ID") && columns.contains("Account_ID")) m_leadingColumns = columns.size(); MAcctSchemaElement ase = elements[i]; String columnName = ase.getColumnName(); if (columnName.startsWith("UserElement")) { if (columnName.indexOf('1') != -1) m_ref1 = ase.getDisplayColumnName(); else m_ref2 = ase.getDisplayColumnName(); } if (!columns.contains(columnName)) columns.add(columnName); } if (m_leadingColumns == 0 && columns.contains("AD_Org_ID") && columns.contains("Account_ID")) m_leadingColumns = columns.size(); return columns; } // createKeyColumns }