1 14 package org.compiere.model; 15 16 import java.sql.*; 17 import java.util.*; 18 import java.math.*; 19 import java.text.*; 20 import java.beans.*; 21 import java.io.*; 22 23 import org.compiere.util.*; 24 25 48 public final class MTab implements DataStatusListener, Serializable 49 { 50 57 public MTab(MTabVO vo) 58 { 59 m_vo = vo; 60 m_mTable = new MTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true); 62 m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView); 63 m_mTable.setDeleteable(m_vo.IsDeleteable); 64 initTab(false); 67 } 76 77 private MTabVO m_vo; 78 79 80 private MTable m_mTable = null; 81 82 private String m_keyColumnName = ""; 83 private String m_linkColumnName = ""; 84 private String m_extendedWhere; 85 86 private HashMap m_Attachment = null; 87 88 private ArrayList m_Lock = null; 89 90 91 private int m_currentRow = -1; 92 93 94 private PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this); 95 96 public static final String PROPERTY = "CurrentRow"; 97 98 private Vector m_dataStatusListeners = null; 99 private DataStatusEvent m_DataStatusEvent = null; 100 private MQuery m_query = new MQuery(); 102 private String m_oldQuery = "0=9"; 103 private String m_linkValue = "999999"; 104 105 106 private String [] m_OrderBys = new String [2]; 107 108 private ArrayList m_parents = new ArrayList(2); 109 110 111 private MultiMap m_depOnField = new MultiMap(); 112 113 114 private Loader m_loader = null; 115 116 private volatile boolean m_loadComplete = false; 117 118 private boolean m_included = false; 119 120 121 122 125 class Loader extends Thread 126 { 127 130 public void run() 131 { 132 initTab (true); 133 } } 136 139 private void waitLoadCompete() 140 { 141 if (m_loadComplete) 142 return; 143 m_loader.setPriority(Thread.NORM_PRIORITY); 145 Log.trace(Log.l1_User, "MTab.waitLoadComplete"); 146 while (m_loader.isAlive()) 147 { 148 try 149 { 150 Thread.sleep(100); } 152 catch (Exception e) 153 { 154 Log.error("MTab.waitLoadComplete", e); 155 } 156 } 157 Log.trace(Log.l1_User, "MTab.waitLoadComplete - fini"); 158 } 160 165 private boolean initTab (boolean async) 166 { 167 Log.trace(Log.l3_Util, "MTab.initTab #" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause); 168 169 m_extendedWhere = m_vo.WhereClause; 170 171 172 if (!loadFields()) 174 { 175 m_loadComplete = true; 176 return false; 177 } 178 179 m_mTable.setOrderClause(getOrderByClause(m_vo.onlyCurrentRows)); 181 182 if (async) 183 Log.trace(Log.l3_Util, "MTab.initTab #" + m_vo.TabNo + " - Async=" + async, "fini"); 184 m_loadComplete = true; 185 return true; 186 } 188 191 protected void dispose() 192 { 193 Log.trace(Log.l3_Util, "MTab.dispose #" + m_vo.TabNo); 194 m_OrderBys = null; 195 m_parents.clear(); 197 m_parents = null; 198 m_mTable.close (true); m_mTable = null; 201 m_depOnField.clear(); 203 m_depOnField = null; 204 if (m_Attachment != null) 205 m_Attachment.clear(); 206 m_Attachment = null; 207 m_vo.Fields.clear(); 209 m_vo.Fields = null; 210 m_vo = null; 211 } 213 214 219 private boolean loadFields() 220 { 221 Log.trace(Log.l3_Util, "MTab.loadFields #" + m_vo.TabNo); 222 223 if (m_vo.Fields == null) 224 return false; 225 226 if (!m_vo.IsView) 228 { 229 MField rowID = new MField (MFieldVO.createRowID (m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID)); 230 m_mTable.addField(rowID); 231 } 232 233 for (int f = 0; f < m_vo.Fields.size(); f++) 235 { 236 MFieldVO voF = (MFieldVO)m_vo.Fields.get(f); 237 if (voF != null) 239 { 240 MField field = new MField (voF); 241 String columnName = field.getColumnName(); 242 if (field.isKey()) 244 { 245 if (m_vo.IsView) voF.initRowID(); 247 m_keyColumnName = columnName; 248 } 249 if (field.isParent()) 251 m_parents.add(columnName); 252 if (field.getSortNo() == 1) 254 m_OrderBys[0] = columnName; 255 else if (field.getSortNo() == 2) 256 m_OrderBys[1] = columnName; 257 m_mTable.addField(field); 259 260 ArrayList list = field.getDependentOn(); 262 for (int i = 0; i < list.size(); i++) 263 m_depOnField.put(list.get(i), field); if (columnName.equals("IsActive") || columnName.equals("Processed")) 266 m_depOnField.put(columnName, null); 267 } 268 } 270 if (m_mTable.getField("Created") == null) 272 { 273 MField created = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, true, true)); 274 m_mTable.addField(created); 275 } 276 if (m_mTable.getField("CreatedBy") == null) 277 { 278 MField createdBy = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, true, false)); 279 m_mTable.addField(createdBy); 280 } 281 if (m_mTable.getField("Updated") == null) 282 { 283 MField updated = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, false, true)); 284 m_mTable.addField(updated); 285 } 286 if (m_mTable.getField("UpdatedBy") == null) 287 { 288 MField updatedBy = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, false, false)); 289 m_mTable.addField(updatedBy); 290 } 291 return true; 292 } 294 300 public MTable getTableModel() 301 { 302 return m_mTable; 303 } 305 309 public javax.swing.Icon getIcon() 310 { 311 if (m_vo.AD_Image_ID == 0) 312 return null; 313 315 return null; 316 } 318 319 320 325 public boolean isDependentOn (String columnName) 326 { 327 return m_depOnField.containsKey(columnName); 329 } 331 336 public ArrayList getDependentFieldList (String columnName) 337 { 338 return m_depOnField.getValues(columnName); 339 } 341 342 343 347 public void setQuery(MQuery query) 348 { 349 if (query == null) 350 m_query = new MQuery(); 351 else 352 m_query = query; 353 } 355 359 public MQuery getQuery() 360 { 361 return m_query; 362 } 364 368 public boolean isQueryActive() 369 { 370 return m_query.isActive(); 371 } 373 376 public void enableEvents() 377 { 378 m_mTable.addDataStatusListener(this); 380 } 383 394 public void query (boolean onlyCurrentRows) 395 { 396 query (onlyCurrentRows, 1); 397 } 399 411 public void query (boolean onlyCurrentRows, int onlyCurrentDays) 412 { 413 Log.trace(Log.l3_Util, "MTab.query #" + m_vo.TabNo + " - Only Current Rows=" + onlyCurrentRows + ", Days=" + onlyCurrentDays); 414 boolean refresh = m_oldQuery.equals(m_query.getWhereClause()) 416 && m_vo.onlyCurrentRows == onlyCurrentRows && m_vo.onlyCurrentDays == onlyCurrentDays; 417 m_oldQuery = m_query.getWhereClause(); 418 m_vo.onlyCurrentRows = onlyCurrentRows; 419 m_vo.onlyCurrentDays = onlyCurrentDays; 420 421 424 StringBuffer where = new StringBuffer (m_vo.WhereClause); 426 if (isDetail()) 428 { 429 String lc = getLinkColumnName(); 430 if (lc.equals("")) 431 Log.error("MTab.query - no link column"); 432 else 433 { 434 String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc); 435 if (refresh) 437 refresh = m_linkValue.equals(value); 438 m_linkValue = value; 439 if (value.length() == 0) 441 Log.error("MTab.query - no value for link column " + lc); 442 else 443 { 444 if (where.length() != 0) 446 where.append(" AND "); 447 where.append(lc).append("="); 448 if (lc.endsWith("_ID")) 449 where.append(value); 450 else 451 where.append("'").append(value).append("'"); 452 } 453 } 454 } 456 m_extendedWhere = where.toString(); 457 458 if (m_query.isActive()) 460 { 461 String q = validateQuery(m_query); 462 if (q != null) 463 { 464 if (where.length() > 0 ) 465 where.append(" AND "); 466 where.append(q); 467 } 468 } 469 470 473 Log.trace(Log.l3_Util, "MTab.query #" + m_vo.TabNo + " - " + where); 474 if (m_mTable.isOpen()) 475 { 476 if (refresh) 477 m_mTable.dataRefreshAll(); 478 else 479 m_mTable.dataRequery(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); 480 } 481 else 482 { 483 m_mTable.setWhereClause(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays); 484 m_mTable.open(); 485 } 486 setCurrentRow(0, true); 488 } 490 496 private String validateQuery (MQuery query) 497 { 498 if (query == null || query.getRestrictionCount() == 0) 499 return null; 500 501 if (query.getRestrictionCount() != 1) 503 { 504 Log.trace(Log.l6_Database, "MTab.validateQuery - ignored: " + query); 505 return query.getWhereClause(); 506 } 507 508 String colName = query.getColumnName(0); 509 if (colName.indexOf('(') != -1) 511 { 512 Log.trace(Log.l6_Database, "MTab.validateQuery - ignored: " + colName); 513 return query.getWhereClause(); 514 } 515 if (getField(colName) != null) 517 return query.getWhereClause(); 518 519 String sql = "SELECT cc.ColumnName " 521 + "FROM AD_Column c" 522 + " INNER JOIN AD_Ref_Table r ON (c.AD_Reference_Value_ID=r.AD_Reference_ID)" 523 + " INNER JOIN AD_Column cc ON (r.AD_Key=cc.AD_Column_ID) " 524 + "WHERE c.AD_Reference_ID=18" + " AND c.ColumnName=?"; 526 String refColName = null; 527 try 528 { 529 PreparedStatement pstmt = DB.prepareStatement(sql); 530 pstmt.setString(1, colName); 531 ResultSet rs = pstmt.executeQuery(); 532 if (rs.next()) 533 refColName = rs.getString(1); 534 rs.close(); 535 pstmt.close(); 536 } 537 catch (SQLException e) 538 { 539 Log.error("MTab.validateQuery (ref) - Column=" + colName, e); 540 return query.getWhereClause(); 541 } 542 if (refColName != null) 544 { 545 query.setColumnName(0, refColName); 546 if (getField(refColName) != null) 547 { 548 Log.trace(Log.l6_Database, "MTab.validateQuery - Column " + colName + " replaced with " + refColName); 549 return query.getWhereClause(); 550 } 551 colName = refColName; 552 } 553 554 String tableName = null; 556 String tabKeyColumn = getKeyColumnName(); 557 559 sql = "SELECT t.TableName " 560 + "FROM AD_Column c" 561 + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) " 562 + "WHERE c.ColumnName=? AND IsKey='Y'" + " AND EXISTS (SELECT * FROM AD_Column cc" 564 + " WHERE cc.AD_Table_ID=t.AD_Table_ID AND cc.ColumnName=?)"; try 566 { 567 PreparedStatement pstmt = DB.prepareStatement(sql); 568 pstmt.setString(1, colName); 569 pstmt.setString(2, tabKeyColumn); 570 ResultSet rs = pstmt.executeQuery(); 571 if (rs.next()) 572 tableName = rs.getString(1); 573 rs.close(); 574 pstmt.close(); 575 } 576 catch (SQLException e) 577 { 578 Log.error("MTab.validateQuery - Column=" + colName + ", Key=" + tabKeyColumn, e); 579 return null; 580 } 581 if (tableName == null) 584 { 585 Log.trace(Log.l3_Util, "MTab.validateQuery not successfull - Column=" + colName + ", Key=" + tabKeyColumn + ", Query=" + query); 586 return query.getWhereClause(); 587 } 588 589 query.setTableName("xx"); 590 StringBuffer result = new StringBuffer ("EXISTS (SELECT * FROM ") 591 .append(tableName).append(" xx WHERE ") 592 .append(query.getWhereClause(true)) 593 .append(" AND xx.").append(tabKeyColumn).append("=") 594 .append(getTableName()).append(".").append(tabKeyColumn).append(")"); 595 Log.trace(Log.l6_Database, "MTab.validateQuery", result); 596 return result.toString(); 597 } 599 600 603 public void dataRefreshAll () 604 { 605 Log.trace(Log.l3_Util, "MTab.dataRefreshAll #" + m_vo.TabNo); 606 607 int keyNo = m_mTable.getKeyID(m_currentRow); 608 m_mTable.dataRefreshAll(); 609 if (keyNo != -1) 611 { 612 if (keyNo != m_mTable.getKeyID(m_currentRow)) { 614 int size = getRowCount(); 615 for (int i = 0; i < size; i++) 616 { 617 if (keyNo == m_mTable.getKeyID(i)) 618 { 619 m_currentRow = i; 620 break; 621 } 622 } 623 } 624 } 625 setCurrentRow(m_currentRow, true); 626 } 628 631 public void dataRefresh () 632 { 633 dataRefresh (m_currentRow); 634 } 636 640 public void dataRefresh (int row) 641 { 642 Log.trace(Log.l3_Util, "MTab.dataRefresh #" + m_vo.TabNo, "row=" + row); 643 m_mTable.dataRefresh(row); 644 setCurrentRow(row, true); 645 } 647 652 public boolean dataSave(boolean manualCmd) 653 { 654 Log.trace(Log.l3_Util, "MTab.dataSave #" + m_vo.TabNo, "row=" + m_currentRow); 655 boolean retValue = (m_mTable.dataSave(manualCmd) == MTable.SAVE_OK); 656 if (manualCmd) 657 setCurrentRow(m_currentRow, false); 658 return retValue; 659 } 661 662 669 public boolean needSave (boolean rowChange, boolean onlyRealChange) 670 { 671 if (rowChange) 672 { 673 return m_mTable.needSave(-2, onlyRealChange); 674 } 675 else 676 { 677 if (onlyRealChange) 678 return m_mTable.needSave(); 679 else 680 return m_mTable.needSave(onlyRealChange); 681 } 682 } 684 687 public void dataIgnore() 688 { 689 Log.trace(Log.l3_Util, "MTab.dataIgnore #" + m_vo.TabNo); 690 m_mTable.dataIgnore(); 691 setCurrentRow(m_currentRow, false); Log.trace(Log.l3_Util, "MTab.dataIgnore #" + m_vo.TabNo + "- fini"); 693 } 695 701 public boolean dataNew (boolean copy) 702 { 703 Log.trace(Log.l3_Util, "MTab.dataNew #" + m_vo.TabNo); 704 boolean retValue = m_mTable.dataNew (m_currentRow, copy); 705 setCurrentRow(m_currentRow + 1, true); 706 for (int i = 0; i < getFieldCount(); i++) 708 processCallout(getField(i)); 709 for (int i = 0; i < getFieldCount(); i++) 711 getField(i).validateValue(); 712 m_mTable.setChanged(false); 713 return retValue; 714 } 716 720 public boolean dataDelete() 721 { 722 Log.trace(Log.l3_Util, "MTab.dataDelete #" + m_vo.TabNo, "row=" + m_currentRow); 723 boolean retValue = m_mTable.dataDelete(m_currentRow); 724 setCurrentRow(m_currentRow, true); 725 return retValue; 726 } 728 732 public String getName() 733 { 734 return m_vo.Name; 735 } 737 741 public String getDescription() 742 { 743 return m_vo.Description; 744 } 746 750 public String getHelp() 751 { 752 return m_vo.Help; 753 } 755 759 public int getTabLevel() 760 { 761 return m_vo.TabLevel; 762 } 764 768 public String getCommitWarning() 769 { 770 return m_vo.CommitWarning; 771 } 773 777 protected MTable getMTable() 778 { 779 return m_mTable; 780 } 782 786 public String getKeyColumnName() 787 { 788 return m_keyColumnName; 789 } 791 795 public String getLinkColumnName() 796 { 797 return m_linkColumnName; 798 } 800 807 public void setLinkColumnName (String linkColumnName) 808 { 809 if (linkColumnName != null) 810 m_linkColumnName = linkColumnName; 811 else 812 { 813 if (m_vo.AD_Column_ID == 0) 814 return; 815 else 817 { 818 String SQL = "SELECT ColumnName FROM AD_Column WHERE AD_Column_ID=?"; 819 try 820 { 821 PreparedStatement pstmt = DB.prepareStatement(SQL); 822 pstmt.setInt(1, m_vo.AD_Column_ID); ResultSet rs = pstmt.executeQuery(); 824 if (rs.next()) 825 m_linkColumnName = rs.getString(1); 826 rs.close(); 827 pstmt.close(); 828 } 829 catch (SQLException e) 830 { 831 Log.error("MTab.setLinkColumn", e); 832 } 833 Log.trace(Log.l6_Database, "MTab.setLinkColumnName - " + m_vo.AD_Column_ID, m_linkColumnName); 834 } 835 } 836 Env.setContext(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, "LinkColumnName", m_linkColumnName); 837 } 839 849 public boolean isCurrent() 850 { 851 if (!m_mTable.isOpen()) 853 return false; 854 if (!m_oldQuery.equals(m_query.getWhereClause())) 856 return false; 857 if (!isDetail()) 859 return true; 860 String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getLinkColumnName()); 862 return m_linkValue.equals(value); 863 } 865 869 public boolean isOpen() 870 { 871 if (m_mTable != null) 873 return m_mTable.isOpen(); 874 return false; 875 } 877 878 882 public boolean isIncluded() 883 { 884 return m_included; 885 } 887 891 public void setIncluded(boolean isIncluded) 892 { 893 m_included = isIncluded; 894 } 896 900 public boolean isOnlyCurrentRows() 901 { 902 return m_vo.onlyCurrentRows; 903 } 908 public ArrayList getParentColumnNames() 909 { 910 return m_parents; 911 } 913 917 private int getTreeID() 918 { 919 Log.trace(Log.l5_DData, "MTab.getTreeID " + m_vo.TableName); 920 String SQL = "SELECT * FROM AD_ClientInfo WHERE AD_Client=" 921 + Env.getContext(m_vo.ctx, m_vo.WindowNo, "#AD_Client_ID") 922 + " ORDER BY AD_Org DESC"; 923 if (m_vo.TableName.equals("AD_Menu")) 925 return 10; else if (m_vo.TableName.equals("C_ElementValue")) 927 return 20; else if (m_vo.TableName.equals("M_Product")) 929 return 30; else if (m_vo.TableName.equals("C_BPartner")) 931 return 40; else if (m_vo.TableName.equals("AD_Org")) 933 return 50; else if (m_vo.TableName.equals("C_Project")) 935 return 60; return 0; 937 } 939 943 public boolean isDetail() 944 { 945 if (m_parents.size() > 0 || m_vo.AD_Column_ID != 0) 947 return true; 948 return false; 949 } 951 955 public boolean isPrinted() 956 { 957 return m_vo.AD_Process_ID != 0; 958 } 960 964 public int getWindowNo() 965 { 966 return m_vo.WindowNo; 967 } 969 973 public int getTabNo() 974 { 975 return m_vo.TabNo; 976 } 978 982 public int getAD_Process_ID() 983 { 984 return m_vo.AD_Process_ID; 985 } 987 991 public boolean isHighVolume() 992 { 993 return m_vo.IsHighVolume; 994 } 996 1000 public boolean isReadOnly() 1001 { 1002 return m_vo.IsReadOnly; 1003 } 1005 1009 public boolean isSingleRow() 1010 { 1011 return m_vo.IsSingleRow; 1012 } 1014 1019 public void setSingleRow (boolean isSingleRow) 1020 { 1021 m_vo.IsSingleRow = isSingleRow; 1022 } 1024 1025 1029 public boolean isTreeTab() 1030 { 1031 return m_vo.HasTree; 1032 } 1034 1038 public int getAD_Tab_ID() 1039 { 1040 return m_vo.AD_Tab_ID; 1041 } 1043 1047 public int getAD_Table_ID() 1048 { 1049 return m_vo.AD_Table_ID; 1050 } 1052 1056 public int getIncluded_Tab_ID() 1057 { 1058 return m_vo.Included_Tab_ID; 1059 } 1061 1065 public String getTableName() 1066 { 1067 return m_vo.TableName; 1068 } 1070 1074 public String getWhereClause() 1075 { 1076 return m_vo.WhereClause; 1077 } 1079 1083 public boolean isSortTab() 1084 { 1085 return m_vo.IsSortTab; 1086 } 1088 1092 public int getAD_ColumnSortOrder_ID() 1093 { 1094 return m_vo.AD_ColumnSortOrder_ID; 1095 } 1097 1101 public int getAD_ColumnSortYesNo_ID() 1102 { 1103 return m_vo.AD_ColumnSortYesNo_ID; 1104 } 1106 1107 1108 1112 public String getWhereExtended() 1113 { 1114 return m_extendedWhere; 1115 } 1117 1122 private String getOrderByClause(boolean onlyCurrentRows) 1123 { 1124 if (m_vo.OrderByClause.length() == 0 && m_OrderBys[0] != null) 1126 { 1127 m_vo.OrderByClause = m_OrderBys[0]; 1128 if (onlyCurrentRows && !isDetail()) m_vo.OrderByClause += " DESC"; 1130 if (m_OrderBys[1] != null) 1131 m_vo.OrderByClause += "," + m_OrderBys[1]; 1132 } 1133 return m_vo.OrderByClause; 1134 } 1136 1137 1138 1143 public String getTrxInfo() 1144 { 1145 if (m_vo.TableName.startsWith("C_Order") || m_vo.TableName.startsWith("C_Invoice")) 1147 { 1148 int Record_ID; 1149 boolean isOrder = m_vo.TableName.startsWith("C_Order"); 1150 StringBuffer sql = new StringBuffer ("SELECT COUNT(*) AS Lines,c.ISO_Code,o.TotalLines,o.GrandTotal," 1152 + "C_Base_Convert(o.GrandTotal,o.C_Currency_ID,o.AD_Client_ID,SysDate,o.AD_Org_ID) AS ConvAmt "); 1153 if (isOrder) 1154 { 1155 Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Order_ID"); 1156 sql.append("FROM C_Order o, C_Currency c, C_OrderLine l " 1157 + "WHERE o.C_Currency_ID=c.C_Currency_ID" 1158 + " AND o.C_Order_ID=?" 1159 + " AND o.C_Order_ID=l.C_Order_ID "); 1160 } 1161 else 1162 { 1163 Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "C_Invoice_ID"); 1164 sql.append("FROM C_Invoice o, C_Currency c, C_InvoiceLine l " 1165 + "WHERE o.C_Currency_ID=c.C_Currency_ID" 1166 + " AND o.C_Invoice_ID=?" 1167 + " AND o.C_Invoice_ID=l.C_Invoice_ID "); 1168 } 1169 sql.append("GROUP BY o.C_Currency_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.AD_Client_ID, o.AD_Org_ID"); 1170 1171 Log.trace(Log.l3_Util, "MTab.getTrxInfo " + m_vo.TableName + " - " + Record_ID); 1172 MessageFormat mf = null; 1173 try 1174 { 1175 mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary")); 1176 } 1177 catch (Exception e) 1178 { 1179 Log.error("MTab.getTrxInfo - OrderSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary"), e); 1180 } 1181 if (mf == null) 1182 return " "; 1183 1193 Object [] arguments = new Object [5]; 1194 boolean filled = false; 1195 try 1197 { 1198 PreparedStatement pstmt = DB.prepareStatement(sql.toString()); 1199 pstmt.setInt(1, Record_ID); 1200 ResultSet rs = pstmt.executeQuery(); 1201 if (rs.next()) 1202 { 1203 Integer lines = new Integer (rs.getInt(1)); 1205 arguments[0] = lines; 1206 Double lineTotal = new Double (rs.getDouble(3)); 1208 arguments[1] = lineTotal; 1209 Double grandTotal = new Double (rs.getDouble(4)); 1211 arguments[2] = grandTotal; 1212 String currency = rs.getString(2); 1214 arguments[3] = currency; 1215 Double grandEuro = new Double (rs.getDouble(5)); 1217 arguments[4] = grandEuro; 1218 filled = true; 1219 } 1220 rs.close(); 1221 pstmt.close(); 1222 } 1223 catch (SQLException e) 1224 { 1225 Log.error("MTab.getTrxInfo " + m_vo.TableName + "\nSQL=" + sql, e); 1226 } 1227 if (filled) 1228 return mf.format (arguments); 1229 return " "; 1230 } 1232 else if (m_vo.TableName.startsWith("S_TimeExpense") && m_vo.TabNo == 0) 1234 { 1235 int Record_ID = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, "S_TimeExpense_ID"); 1236 Log.trace(Log.l3_Util, "MTab.getTrxInfo " + m_vo.TableName + " - " + Record_ID); 1237 MessageFormat mf = null; 1238 try 1239 { 1240 mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary")); 1241 } 1242 catch (Exception e) 1243 { 1244 Log.error("MTab.getTrxInfo - ExpenseSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary"), e); 1245 } 1246 if (mf == null) 1247 return " "; 1248 1256 Object [] arguments = new Object [3]; 1257 boolean filled = false; 1258 String SQL = "SELECT COUNT(*) AS Lines, SUM(ConvertedAmt*Qty) " 1260 + "FROM S_TimeExpenseLine " 1261 + "WHERE S_TimeExpense_ID=?"; 1262 1263 try 1265 { 1266 PreparedStatement pstmt = DB.prepareStatement(SQL); 1267 pstmt.setInt(1, Record_ID); 1268 ResultSet rs = pstmt.executeQuery(); 1269 if (rs.next()) 1270 { 1271 Integer lines = new Integer (rs.getInt(1)); 1273 arguments[0] = lines; 1274 Double total = new Double (rs.getDouble(2)); 1276 arguments[1] = total; 1277 arguments[2] = " "; 1279 filled = true; 1280 } 1281 rs.close(); 1282 pstmt.close(); 1283 } 1284 catch (SQLException e) 1285 { 1286 Log.error("MTab.getTrxInfo " + m_vo.TableName + "\nSQL=" + SQL, e); 1287 } 1288 if (filled) 1289 return mf.format (arguments); 1290 return " "; 1291 } 1293 1294 return null; 1296 } 1298 1301 private void loadDependentInfo() 1302 { 1303 1306 if (m_vo.TableName.equals("C_Order")) 1307 { 1308 int C_DocTyp_ID = 0; 1309 Integer target = (Integer )getValue("C_DocTypeTarget_ID"); 1310 if (target != null) 1311 C_DocTyp_ID = target.intValue(); 1312 if (C_DocTyp_ID == 0) 1313 return; 1314 1315 String sql = "SELECT DocSubTypeSO FROM C_DocType WHERE C_DocType_ID=?"; 1316 try 1317 { 1318 PreparedStatement pstmt = DB.prepareStatement(sql); 1319 pstmt.setInt(1, C_DocTyp_ID); 1320 ResultSet rs = pstmt.executeQuery(); 1321 if (rs.next()) 1322 Env.setContext(m_vo.ctx, m_vo.WindowNo, "OrderType", rs.getString(1)); 1323 rs.close(); 1324 pstmt.close(); 1325 } 1326 catch (SQLException e) 1327 { 1328 Log.error("MTab.loadOrderType", e); 1329 } 1330 } } 1333 1334 1335 1338 public void loadAttachments() 1339 { 1340 Log.trace(Log.l3_Util, "MTab.loadAttachments #" + m_vo.TabNo); 1341 if (!canHaveAttachment()) 1342 return; 1343 1344 String SQL = "SELECT AD_Attachment_ID, Record_ID FROM AD_Attachment " 1345 + "WHERE AD_Table_ID=?"; 1346 try 1347 { 1348 if (m_Attachment == null) 1349 m_Attachment = new HashMap(); 1350 else 1351 m_Attachment.clear(); 1352 PreparedStatement pstmt = DB.prepareStatement(SQL); 1353 pstmt.setInt(1, m_vo.AD_Table_ID); 1354 ResultSet rs = pstmt.executeQuery(); 1355 while (rs.next()) 1356 { 1357 Integer key = new Integer (rs.getInt(2)); 1358 Integer value = new Integer (rs.getInt(1)); 1359 m_Attachment.put(key, value); 1360 } 1361 rs.close(); 1362 pstmt.close(); 1363 } 1364 catch (SQLException e) 1365 { 1366 Log.error("MTab.loadAttachments", e); 1367 } 1368 Log.trace(Log.l4_Data, "Attachments=" + m_Attachment.size()); 1369 } 1371 1378 public boolean canHaveAttachment() 1379 { 1380 if (getKeyColumnName().endsWith("_ID")) 1381 return true; 1382 return false; 1383 } 1385 1389 public boolean hasAttachment() 1390 { 1391 if (m_Attachment == null) 1392 loadAttachments(); 1393 if (m_Attachment == null || m_Attachment.isEmpty()) 1394 return false; 1395 Integer key = new Integer (m_mTable.getKeyID (m_currentRow)); 1397 return m_Attachment.containsKey(key); 1398 } 1400 1404 public int getAD_AttachmentID() 1405 { 1406 if (m_Attachment == null) 1407 loadAttachments(); 1408 if (m_Attachment.isEmpty()) 1409 return 0; 1410 Integer key = new Integer (m_mTable.getKeyID (m_currentRow)); 1412 Integer value = (Integer )m_Attachment.get(key); 1413 if (value == null) 1414 return 0; 1415 else 1416 return value.intValue(); 1417 } 1419 1420 1421 1422 1425 public void loadLocks() 1426 { 1427 int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"); 1428 Log.trace(Log.l3_Util, "MTab.loadLocks #" + m_vo.TabNo + " - AD_User_ID=" + AD_User_ID); 1429 if (!canHaveAttachment()) 1430 return; 1431 1432 String SQL = "SELECT Record_ID " 1433 + "FROM AD_Private_Access " 1434 + "WHERE AD_User_ID=? AND AD_Table_ID=? AND IsActive='Y' " 1435 + "ORDER BY Record_ID"; 1436 try 1437 { 1438 if (m_Lock == null) 1439 m_Lock = new ArrayList(); 1440 else 1441 m_Lock.clear(); 1442 PreparedStatement pstmt = DB.prepareStatement(SQL); 1443 pstmt.setInt(1, AD_User_ID); 1444 pstmt.setInt(2, m_vo.AD_Table_ID); 1445 ResultSet rs = pstmt.executeQuery(); 1446 while (rs.next()) 1447 { 1448 Integer key = new Integer (rs.getInt(1)); 1449 m_Lock.add(key); 1450 } 1451 rs.close(); 1452 pstmt.close(); 1453 } 1454 catch (SQLException e) 1455 { 1456 Log.error("MTab.loadLocks", e); 1457 } 1458 Log.trace(Log.l4_Data, "Locks=" + m_Lock.size()); 1459 } 1461 1464 public boolean isLocked() 1465 { 1466 if (!MRole.getDefault(m_vo.ctx, false).isPersonalLock()) 1467 return false; 1468 if (m_Lock == null) 1469 loadLocks(); 1470 if (m_Lock == null || m_Lock.isEmpty()) 1471 return false; 1472 Integer key = new Integer (m_mTable.getKeyID (m_currentRow)); 1474 return m_Lock.contains(key); 1475 } 1477 1482 public void lock (Properties ctx, int Record_ID, boolean lock) 1483 { 1484 int AD_User_ID = Env.getContextAsInt(ctx, "#AD_User_ID"); 1485 Log.trace (Log.l3_Util, "MTab.lock - " + lock + ", AD_User_ID=" + AD_User_ID + ", AD_Table_ID=" + m_vo.AD_Table_ID + ", Record_ID=" + Record_ID); 1486 MPrivateAccess access = MPrivateAccess.get (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); 1487 if (access == null) 1488 access = new MPrivateAccess (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); 1489 access.setIsActive(lock); 1490 access.save(); 1491 loadLocks(); 1493 } 1495 1496 1497 1504 public void dataStatusChanged (DataStatusEvent e) 1505 { 1506 Log.trace(Log.l3_Util, "MTab.dataStatusChanged #" + m_vo.TabNo, e.toString()); 1507 int oldCurrentRow = e.getCurrentRow(); 1508 m_DataStatusEvent = e; String msg = m_DataStatusEvent.getAD_Message(); 1511 if (msg != null && msg.equals("Sorted")) 1512 setCurrentRow(0, true); 1513 m_DataStatusEvent.setCurrentRow(m_currentRow); 1515 if (oldCurrentRow == m_currentRow) 1517 { 1518 MField field = m_mTable.getField(e.getChangedColumn()); 1519 if (field != null) 1520 { 1521 Object value = m_mTable.getValueAt(m_currentRow, e.getChangedColumn()); 1522 field.setValue(value, m_mTable.isInserting()); 1523 } 1524 } 1525 else fireDataStatusChanged(m_DataStatusEvent); 1527 } 1530 1534 private void fireDataStatusChanged (DataStatusEvent e) 1535 { 1536 Log.trace(Log.l4_Data, "MTab.fireDataStatusChanged", e.toString()); 1537 if (m_dataStatusListeners != null) 1538 { 1539 if (e.getCurrentRow() >= 0) 1541 { 1542 e.Created = (Timestamp)getValue("Created"); 1543 e.CreatedBy = getValue("CreatedBy"); 1544 e.Updated = (Timestamp)getValue("Updated"); 1545 e.UpdatedBy = getValue("UpdatedBy"); 1546 StringBuffer info = new StringBuffer (getTableName()); 1548 if (m_keyColumnName != null && m_keyColumnName.length() > 0) 1550 { 1551 info.append(" - ") 1552 .append(m_keyColumnName).append("=").append(getValue(m_keyColumnName)); 1553 } 1554 else { 1556 for (int i = 0; i < m_parents.size(); i++) 1557 { 1558 String keyCol = (String )m_parents.get(i); 1559 info.append(" - ") 1560 .append(keyCol).append("=").append(getValue(keyCol)); 1561 } 1562 } 1563 e.Info = info.toString(); 1564 } 1565 e.setInserting(m_mTable.isInserting()); 1566 Vector listeners = m_dataStatusListeners; 1568 int count = listeners.size(); 1569 for (int i = 0; i < count; i++) 1570 ((DataStatusListener) listeners.elementAt(i)).dataStatusChanged(e); 1571 } 1572 } 1575 1580 protected void fireDataStatusEEvent(String AD_Message, String info) 1581 { 1582 m_mTable.fireDataStatusEEvent(AD_Message, info); 1583 } 1585 1589 protected void fireDataStatusEEvent (ValueNamePair errorLog) 1590 { 1591 if (errorLog != null) 1592 m_mTable.fireDataStatusEEvent(errorLog); 1593 } 1595 1599 public int getCurrentRow() 1600 { 1601 if (m_currentRow != verifyRow(m_currentRow)) 1602 setCurrentRow(m_mTable.getRowCount()-1, true); 1603 return m_currentRow; 1604 } 1606 1610 public int getCurrentKeyID() 1611 { 1612 return m_mTable.getKeyID(m_currentRow); 1613 } 1615 1620 public int getKeyID (int row) 1621 { 1622 return m_mTable.getKeyID (row); 1623 } 1625 1632 public int navigate (int targetRow) 1633 { 1634 if (targetRow == m_currentRow) 1636 return m_currentRow; 1637 Log.trace(Log.l1_User, "MTab.navigate - Row=" + targetRow); 1638 1639 int newRow = verifyRow(targetRow); 1641 1642 m_mTable.dataSave(newRow, false); 1644 1645 return setCurrentRow(newRow, true); 1647 } 1649 1654 public int navigateRelative (int rowChange) 1655 { 1656 return navigate (m_currentRow + rowChange); 1657 } 1659 1663 public int navigateCurrent() 1664 { 1665 Log.trace(Log.l1_User, "MTab.navigateCurrent"); 1666 return setCurrentRow(m_currentRow, true); 1667 } 1669 1674 private int verifyRow (int targetRow) 1675 { 1676 int newRow = targetRow; 1677 if (!m_mTable.isOpen()) 1679 { 1680 Log.error("MTab.verifyRow - Table not open"); 1681 return -1; 1682 } 1683 int rows = getRowCount(); 1685 if (rows == 0) 1686 { 1687 Log.trace(Log.l4_Data, "MTab.verifyRow", "No Rows"); 1688 return -1; 1689 } 1690 if (newRow >= rows) 1691 { 1692 newRow = rows-1; 1693 Log.trace(Log.l4_Data, "MTab.verifyRow", "Set to max Row: " + newRow); 1694 } 1695 else if (newRow < 0) 1696 { 1697 newRow = 0; 1698 Log.trace(Log.l4_Data, "MTab.verifyRow", "Set to first Row"); 1699 } 1700 return newRow; 1701 } 1703 1710 private int setCurrentRow (int newCurrentRow, boolean fireEvents) 1711 { 1712 int oldCurrentRow = m_currentRow; 1713 m_currentRow = verifyRow (newCurrentRow); 1714 Log.trace(Log.l4_Data, "MTab.setCurrentRow = " + m_currentRow, "fire=" + fireEvents); 1715 1716 int size = m_mTable.getColumnCount(); 1718 for (int i = 0; i < size; i++) 1719 { 1720 MField mField = m_mTable.getField(i); 1721 if (m_currentRow >= 0) 1723 { 1724 Object value = m_mTable.getValueAt(m_currentRow, i); 1725 mField.setValue(value, m_mTable.isInserting()); 1726 if (m_mTable.isInserting()) mField.validateValue(); 1728 } 1729 else 1730 { mField.setValue(); 1735 } 1736 } 1737 loadDependentInfo(); 1738 1739 if (!fireEvents) return m_currentRow; 1741 1742 m_propertyChangeSupport.firePropertyChange(PROPERTY, oldCurrentRow, m_currentRow); 1744 1745 if (m_DataStatusEvent == null) 1747 { 1748 Log.trace(Log.l5_DData, "MTab.setCurrentRow - no existing data status event"); 1749 } 1750 else 1751 { 1752 m_DataStatusEvent.setCurrentRow(m_currentRow); 1753 String status = m_DataStatusEvent.getAD_Message(); 1754 if (status == null || status.length() == 0) 1755 m_DataStatusEvent.setInfo("NavigateOrUpdate", null, false); 1756 fireDataStatusChanged(m_DataStatusEvent); 1757 } 1758 return m_currentRow; 1759 } 1761 1762 1763 1767 public int getRowCount() 1768 { 1769 int count = m_mTable.getRowCount(); 1770 if (count == 0 && m_mTable.isLoading()) 1772 { 1773 try 1774 { 1775 Thread.sleep(100); } 1777 catch (Exception e) {} 1778 count = m_mTable.getRowCount(); 1779 } 1780 return count; 1781 } 1783 1787 public int getFieldCount() 1788 { 1789 return m_mTable.getColumnCount(); 1790 } 1792 1797 public MField getField (int index) 1798 { 1799 return m_mTable.getField(index); 1800 } 1802 1807 public MField getField (String columnName) 1808 { 1809 return m_mTable.getField(columnName); 1810 } 1812 1818 public String setValue (String columnName, Object value) 1819 { 1820 if (columnName == null) 1821 return "NoColumn"; 1822 return setValue(m_mTable.getField(columnName), value); 1823 } 1825 1831 public String setValue (MField field, Object value) 1832 { 1833 if (field == null) 1834 return "NoField"; 1835 1836 Log.trace(Log.l3_Util, "MTab.setValue - " 1837 + field.getColumnName() + "=" + value + " for row=" + m_currentRow); 1838 1839 int col = m_mTable.findColumn(field.getColumnName()); 1840 m_mTable.setValueAt(value, m_currentRow, col, false); 1841 return processFieldChange (field); 1843 } 1845 1852 public String processFieldChange (MField changedField) 1853 { 1854 processDependencies (changedField); 1855 return processCallout (changedField); 1856 } 1858 1862 private void processDependencies (MField changedField) 1863 { 1864 String columnName = changedField.getColumnName(); 1865 1867 if (!isDependentOn(columnName)) 1869 return; 1870 1871 ArrayList list = getDependentFieldList(columnName); 1873 for (int i = 0; i < list.size(); i++) 1874 { 1875 MField dependentField = (MField)list.get(i); 1876 if (dependentField != null && dependentField.getLookup() instanceof MLookup) 1879 { 1880 MLookup mLookup = (MLookup)dependentField.getLookup(); 1881 if (mLookup.getValidation().indexOf("@"+columnName+"@") != -1) 1884 { 1885 Log.trace(Log.l6_Database, "MTab.processDependencies", 1886 columnName + " changed - " + dependentField.getColumnName() + " set to null"); 1887 setValue(dependentField, null); 1889 } 1890 } 1891 } } 1894 1909 private String processCallout (MField field) 1910 { 1911 String callout = field.getCallout(); 1912 if (callout.length() == 0) 1913 return ""; 1914 1915 Object value = field.getValue(); 1916 Object oldValue = field.getOldValue(); 1917 Log.trace(Log.l3_Util, "MTab.processCallout - " + field.getColumnName() + "=" + value 1918 + " (" + callout + ") - old=" + oldValue); 1919 1920 StringTokenizer st = new StringTokenizer(callout, ";", false); 1921 while (st.hasMoreTokens()) { 1923 String cmd = st.nextToken().trim(); 1924 Callout call = null; 1925 String method = null; 1926 int methodStart = cmd.lastIndexOf("."); 1927 try 1928 { 1929 if (methodStart == -1) { 1932 if (cmd.charAt(0) == 'S' && cmd.charAt(2) == '_') 1934 { 1935 call = new CalloutSystem(); 1936 if (cmd.length() > 3) 1937 method = cmd.substring(3); 1938 } 1939 else if (cmd.charAt(0) == 'U' && cmd.charAt(2) == '_') 1940 { 1941 Class cClass = Class.forName("com.compiere.custom.CalloutUser"); 1942 call = (Callout)cClass.newInstance(); 1943 if (cmd.length() > 3) 1944 method = cmd.substring(3); 1945 } 1946 else 1947 { 1948 call = new CalloutSystem(); 1949 method = cmd; 1950 } 1951 } else 1953 { 1954 Class cClass = Class.forName(cmd.substring(0,methodStart)); 1955 call = (Callout)cClass.newInstance(); 1956 method = cmd.substring(methodStart+1); 1957 } 1958 } 1959 catch (Exception e) 1960 { 1961 Log.error("MTab.processCallout", e); 1962 return "CalloutNameInvalid = " + cmd + " (" + e.toString() + ")"; 1963 } 1964 1965 if (call == null || method == null || method.length() == 0) 1966 return "CalloutNameInvalid = " + method; 1967 1968 String retValue = ""; 1969 try 1970 { 1971 retValue = call.start(m_vo.ctx, method, m_vo.WindowNo, this, field, value, oldValue); 1972 } 1973 catch (Exception e) 1974 { 1975 Log.error("MTab.processCallout", e); 1976 retValue = "CalloutNameInvalid " + e.toString(); 1977 } 1978 if (!retValue.equals("")) { 1980 Log.error("MTab.processCallout - " + retValue); 1981 return retValue; 1982 } 1983 } return ""; 1985 } 1987 1988 1993 public Object getValue (String columnName) 1994 { 1995 if (columnName == null) 1996 return null; 1997 MField field = m_mTable.getField(columnName); 1998 return getValue(field); 1999 } 2001 2006 public Object getValue (MField field) 2007 { 2008 if (field == null) 2009 return null; 2010 return field.getValue(); 2011 } 2013 2019 public Object getValue (int row, String columnName) 2020 { 2021 int col = m_mTable.findColumn(columnName); 2022 if (col == -1) 2023 return null; 2024 return m_mTable.getValueAt(row, col); 2025 } 2027 2031 public String toString() 2032 { 2033 String retValue = "MTab #" + m_vo.TabNo; 2034 if (m_vo != null) 2035 retValue += " " + m_vo.Name + " (" + m_vo.AD_Tab_ID + ")"; 2036 return retValue; 2037 } 2039 2040 2041 2044 public synchronized void removePropertyChangeListener(PropertyChangeListener l) 2045 { 2046 m_propertyChangeSupport.removePropertyChangeListener(l); 2047 } 2048 2051 public synchronized void addPropertyChangeListener(PropertyChangeListener l) 2052 { 2053 m_propertyChangeSupport.addPropertyChangeListener(l); 2054 } 2055 2056 2059 public synchronized void removeDataStatusListener(DataStatusListener l) 2060 { 2061 if (m_dataStatusListeners != null && m_dataStatusListeners.contains(l)) 2062 { 2063 Vector v = (Vector) m_dataStatusListeners.clone(); 2064 v.removeElement(l); 2065 m_dataStatusListeners = v; 2066 } 2067 } 2068 2071 public synchronized void addDataStatusListener(DataStatusListener l) 2072 { 2073 Vector v = m_dataStatusListeners == null ? new Vector(2) : (Vector) m_dataStatusListeners.clone(); 2074 if (!v.contains(l)) 2075 { 2076 v.addElement(l); 2077 m_dataStatusListeners = v; 2078 } 2079 } 2080 2081} | Popular Tags |