KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > apps > form > VAllocation


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.apps.form;
15
16 import java.awt.*;
17 import javax.swing.*;
18 import javax.swing.table.*;
19 import javax.swing.event.*;
20
21 import java.awt.event.*;
22 import java.util.*;
23 import java.math.*;
24 import java.text.*;
25 import java.beans.*;
26 import java.sql.*;
27
28 import org.compiere.util.*;
29 import org.compiere.apps.*;
30 import org.compiere.grid.ed.*;
31 import org.compiere.minigrid.*;
32 import org.compiere.model.*;
33 import org.compiere.plaf.*;
34 import org.compiere.swing.*;
35
36 /**
37  * Allocation Form
38  *
39  * @author Jorg Janke
40  * @version $Id: VAllocation.java,v 1.24 2003/09/29 01:04:41 jjanke Exp $
41  */

42 public class VAllocation extends CPanel
43     implements FormPanel, ActionListener, TableModelListener, VetoableChangeListener
44 {
45     /**
46      * Allocation Constructor
47      */

48     public VAllocation()
49     {
50     } // VAllocation
51

52     /**
53      * Initialize Panel
54      * @param WindowNo window
55      * @param frame frame
56      */

57     public void init (int WindowNo, FormFrame frame)
58     {
59         m_WindowNo = WindowNo;
60         m_frame = frame;
61         Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", "Y"); // defaults to no
62
m_C_Currency_ID = Env.getContextAsInt(Env.getCtx(), "$C_Currency_ID"); // default
63
//
64
Log.trace(Log.l1_User, "VAllocation.init - Currency=" + m_C_Currency_ID);
65         try
66         {
67             dynInit();
68             jbInit();
69             calculate();
70             frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
71             frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
72         }
73         catch(Exception JavaDoc e)
74         {
75             Log.error("VAllocation.init", e);
76         }
77     } // init
78

79     /** Window No */
80     private int m_WindowNo = 0;
81     /** FormFrame */
82     private FormFrame m_frame;
83
84     private boolean m_calculating = false;
85     private int m_C_Currency_ID = 0;
86     private int m_C_BPartner_ID = 0;
87     private int m_noInvoices = 0;
88     private int m_noPayments = 0;
89
90     // Index changed if multi-currency
91
private int i_payment = 7;
92     //
93
private int i_open = 6;
94     private int i_discount = 7;
95     private int i_writeOff = 8;
96     private int i_applied = 9;
97     private int i_multiplier = 10;
98     //
99
private CPanel mainPanel = new CPanel();
100     private BorderLayout mainLayout = new BorderLayout();
101     private CPanel parameterPanel = new CPanel();
102     private CPanel allocationPanel = new CPanel();
103     private GridBagLayout parameterLayout = new GridBagLayout();
104     private JLabel bpartnerLabel = new JLabel();
105     private VLookup bpartnerSearch = new VLookup();
106     private MiniTable invoiceTable = new MiniTable();
107     private MiniTable paymentTable = new MiniTable();
108     private JSplitPane infoPanel = new JSplitPane();
109     private CPanel paymentPanel = new CPanel();
110     private CPanel invoicePanel = new CPanel();
111     private JLabel paymentLabel = new JLabel();
112     private JLabel invoiceLabel = new JLabel();
113     private BorderLayout paymentLayout = new BorderLayout();
114     private BorderLayout invoiceLayout = new BorderLayout();
115     private JLabel paymentInfo = new JLabel();
116     private JLabel invoiceInfo = new JLabel();
117     private JScrollPane paymentScrollPane = new JScrollPane();
118     private JScrollPane invoiceScrollPane = new JScrollPane();
119     private GridBagLayout allocationLayout = new GridBagLayout();
120     private JLabel differenceLabel = new JLabel();
121     private JTextField differenceField = new JTextField();
122     private JButton allocateButton = new JButton();
123     private JLabel currencyLabel = new JLabel();
124     private VLookup currencyPick = new VLookup();
125     private JCheckBox multiCurrency = new JCheckBox();
126     private JLabel allocCurrencyLabel = new JLabel();
127     private StatusBar statusBar = new StatusBar();
128     private JLabel dateLabel = new JLabel();
129     private VDate dateField = new VDate();
130     private JCheckBox autoCalc = new JCheckBox();
131
132     /**
133      * Static Init
134      * @throws Exception
135      */

136     private void jbInit() throws Exception JavaDoc
137     {
138         CompiereColor.setBackground(this);
139         //
140
mainPanel.setLayout(mainLayout);
141         dateLabel.setText(Msg.getMsg(Env.getCtx(), "Date"));
142         autoCalc.setSelected(true);
143         autoCalc.setText(Msg.getMsg(Env.getCtx(), "AutoCalc"));
144         //
145
parameterPanel.setLayout(parameterLayout);
146         allocationPanel.setLayout(allocationLayout);
147         bpartnerLabel.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
148         paymentLabel.setRequestFocusEnabled(false);
149         paymentLabel.setText(" " + Msg.translate(Env.getCtx(), "C_Payment_ID"));
150         invoiceLabel.setRequestFocusEnabled(false);
151         invoiceLabel.setText(" " + Msg.translate(Env.getCtx(), "C_Invoice_ID"));
152         paymentPanel.setLayout(paymentLayout);
153         invoicePanel.setLayout(invoiceLayout);
154         invoiceInfo.setHorizontalAlignment(SwingConstants.RIGHT);
155         invoiceInfo.setHorizontalTextPosition(SwingConstants.RIGHT);
156         invoiceInfo.setText(".");
157         paymentInfo.setHorizontalAlignment(SwingConstants.RIGHT);
158         paymentInfo.setHorizontalTextPosition(SwingConstants.RIGHT);
159         paymentInfo.setText(".");
160         differenceLabel.setText(Msg.getMsg(Env.getCtx(), "Difference"));
161         differenceField.setBackground(CompierePLAF.getFieldBackground_Inactive());
162         differenceField.setEditable(false);
163         differenceField.setText("0");
164         differenceField.setColumns(8);
165         differenceField.setHorizontalAlignment(SwingConstants.RIGHT);
166         allocateButton.setText(Msg.getMsg(Env.getCtx(), "Process"));
167         allocateButton.addActionListener(this);
168         currencyLabel.setText(Msg.translate(Env.getCtx(), "C_Currency_ID"));
169         multiCurrency.setText(Msg.getMsg(Env.getCtx(), "MultiCurrency"));
170         multiCurrency.addActionListener(this);
171         allocCurrencyLabel.setText(".");
172         invoiceScrollPane.setPreferredSize(new Dimension(200, 200));
173         paymentScrollPane.setPreferredSize(new Dimension(200, 200));
174         mainPanel.add(parameterPanel, BorderLayout.NORTH);
175         parameterPanel.add(bpartnerLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
176             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
177         parameterPanel.add(bpartnerSearch, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
178             ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
179         parameterPanel.add(dateLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
180             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
181         parameterPanel.add(dateField, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
182             ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
183         parameterPanel.add(currencyLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
184             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
185         parameterPanel.add(currencyPick, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
186             ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
187         parameterPanel.add(multiCurrency, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0
188             ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
189         mainPanel.add(allocationPanel, BorderLayout.SOUTH);
190         allocationPanel.add(differenceLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
191             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 0), 0, 0));
192         allocationPanel.add(differenceField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
193             ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
194         allocationPanel.add(allocateButton, new GridBagConstraints(5, 0, 1, 1, 0.0, 0.0
195             ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
196         allocationPanel.add(allocCurrencyLabel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
197             ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
198         allocationPanel.add(autoCalc, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0
199             ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
200         paymentPanel.add(paymentLabel, BorderLayout.NORTH);
201         paymentPanel.add(paymentInfo, BorderLayout.SOUTH);
202         paymentPanel.add(paymentScrollPane, BorderLayout.CENTER);
203         paymentScrollPane.getViewport().add(paymentTable, null);
204         invoicePanel.add(invoiceLabel, BorderLayout.NORTH);
205         invoicePanel.add(invoiceInfo, BorderLayout.SOUTH);
206         invoicePanel.add(invoiceScrollPane, BorderLayout.CENTER);
207         invoiceScrollPane.getViewport().add(invoiceTable, null);
208         //
209
mainPanel.add(infoPanel, BorderLayout.CENTER);
210         infoPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
211         infoPanel.setBorder(BorderFactory.createEtchedBorder());
212         infoPanel.setTopComponent(paymentPanel);
213         infoPanel.setBottomComponent(invoicePanel);
214         infoPanel.add(paymentPanel, JSplitPane.TOP);
215         infoPanel.add(invoicePanel, JSplitPane.BOTTOM);
216         infoPanel.setContinuousLayout(true);
217         infoPanel.setPreferredSize(new Dimension(670,250));
218         infoPanel.setDividerLocation(110);
219     } // jbInit
220

221     /**
222      * Dispose
223      */

224     public void dispose()
225     {
226         m_frame.dispose();
227     } // dispose
228

229     /**
230      * Dynamic Init (prepare dynamic fields)
231      * @throws Exception if Lookups cannot be initialized
232      */

233     private void dynInit() throws Exception JavaDoc
234     {
235         // Currency
236
int AD_Column_ID = 3505; // C_Invoice.C_Currency_ID
237
MLookup lookupCur = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.TableDir);
238         currencyPick = new VLookup("C_Currency_ID", true, false, true, lookupCur, DisplayType.TableDir, m_WindowNo);
239         currencyPick.setValue(new Integer JavaDoc(m_C_Currency_ID));
240         currencyPick.addVetoableChangeListener(this);
241
242         // BPartner
243
AD_Column_ID = 3499; // C_Invoice.C_BPartner_ID
244
MLookup lookupBP = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Search);
245         bpartnerSearch = new VLookup("C_BPartner_ID", true, false, true, lookupBP, DisplayType.Search, m_WindowNo);
246         bpartnerSearch.addVetoableChangeListener(this);
247
248         // Translation
249
statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "AllocateStatus"));
250         statusBar.setStatusDB("");
251
252         // Date set to today
253
dateField.setValue(new Timestamp(System.currentTimeMillis()));
254         dateField.addVetoableChangeListener(this);
255     } // dynInit
256

257     /**
258      * Load Business Partner Info
259      * - Payments
260      * - Invoices
261      */

262     private void loadBPartner ()
263     {
264         Log.trace(Log.l3_Util, "VAllocation.loadBPartner - BPartner="
265             + m_C_BPartner_ID + ", Cur=" + m_C_Currency_ID);
266         // Need to have both values
267
if (m_C_BPartner_ID == 0 || m_C_Currency_ID == 0)
268             return;
269
270         /********************************
271          * Load unallocated Payments
272          * 1-TrxDate, 2-DocumentNo, (3-Currency, 4-PayAmt,)
273          * 5-ConvAmt, 6-ConvOpen, 7-Allocated
274          */

275         Vector data = new Vector();
276         StringBuffer JavaDoc sql = new StringBuffer JavaDoc("SELECT p.DateTrx,p.DocumentNo,p.C_Payment_ID," // 1..3
277
+ "c.ISO_Code,p.PayAmt," // 4..5
278
+ "C_Currency_Convert(p.PayAmt,p.C_Currency_ID,?,null,null,p.AD_Client_ID,p.AD_Org_ID),"// 6 #1
279
+ "C_Currency_Convert(C_Payment_Available(C_Payment_ID),p.C_Currency_ID,?,null,null,p.AD_Client_ID,p.AD_Org_ID)*p.MultiplierAP," // 7 #2
280
+ "p.MultiplierAP "
281             + "FROM C_Payment_v p" // Corrected for AP/AR
282
+ " INNER JOIN C_Currency c ON (p.C_Currency_ID=c.C_Currency_ID) "
283             + "WHERE p.IsAllocated='N' AND p.Processed='Y'"
284             + " AND p.C_BPartner_ID=?"); // #3
285
if (!multiCurrency.isSelected())
286             sql.append(" AND p.C_Currency_ID=?"); // #4
287
sql.append(" ORDER BY p.DateTrx,p.DocumentNo");
288         Log.trace(Log.l5_DData, "PaySQL=" + sql.toString());
289         try
290         {
291             PreparedStatement pstmt = DB.prepareStatement(sql.toString());
292             pstmt.setInt(1, m_C_Currency_ID);
293             pstmt.setInt(2, m_C_Currency_ID);
294             pstmt.setInt(3, m_C_BPartner_ID);
295             if (!multiCurrency.isSelected())
296                 pstmt.setInt(4, m_C_Currency_ID);
297             ResultSet rs = pstmt.executeQuery();
298             while (rs.next())
299             {
300                 Vector line = new Vector();
301                 line.add(new Boolean JavaDoc(false)); // 0-Selection
302
line.add(rs.getTimestamp(1)); // 1-TrxDate
303
KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(2));
304                 line.add(pp); // 2-DocumentNo
305
if (multiCurrency.isSelected())
306                 {
307                     line.add(rs.getString(4)); // 3-Currency
308
line.add(rs.getBigDecimal(5)); // 4-PayAmt
309
}
310                 line.add(rs.getBigDecimal(6)); // 3/5-ConvAmt
311
line.add(rs.getBigDecimal(7)); // 4/6-ConvOpen
312
line.add(Env.ZERO); // 5/7-Payment
313
line.add(rs.getBigDecimal(8)); // 6/8-Multiplier
314
data.add(line);
315             }
316             rs.close();
317             pstmt.close();
318         }
319         catch (SQLException e)
320         {
321             Log.error ("VAllocation.loadBPartner(payment)", e);
322         }
323         // Remove previous listeners
324
paymentTable.getModel().removeTableModelListener(this);
325         // Header Info
326
Vector columnNames = new Vector();
327         columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
328         columnNames.add(Msg.translate(Env.getCtx(), "Date"));
329         columnNames.add(Msg.translate(Env.getCtx(), "DocumentNo"));
330         if (multiCurrency.isSelected())
331         {
332             columnNames.add(Msg.getMsg(Env.getCtx(), "TrxCurrency"));
333             columnNames.add(Msg.translate(Env.getCtx(), "Amount"));
334         }
335         columnNames.add(Msg.getMsg(Env.getCtx(), "ConvertedAmount"));
336         columnNames.add(Msg.getMsg(Env.getCtx(), "OpenAmt"));
337         columnNames.add(Msg.getMsg(Env.getCtx(), "AppliedAmt"));
338         columnNames.add(" "); // Multiplier
339

340         // Set Model
341
DefaultTableModel modelP = new DefaultTableModel(data, columnNames);
342         modelP.addTableModelListener(this);
343         paymentTable.setModel(modelP);
344         //
345
int i = 0;
346         paymentTable.setColumnClass(i++, Boolean JavaDoc.class, false); // 0-Selection
347
paymentTable.setColumnClass(i++, Timestamp.class, true); // 1-TrxDate
348
paymentTable.setColumnClass(i++, String JavaDoc.class, true); // 2-Value
349
if (multiCurrency.isSelected())
350         {
351             paymentTable.setColumnClass(i++, String JavaDoc.class, true); // 3-Currency
352
paymentTable.setColumnClass(i++, BigDecimal.class, true); // 4-PayAmt
353
}
354         paymentTable.setColumnClass(i++, BigDecimal.class, true); // 5-ConvAmt
355
paymentTable.setColumnClass(i++, BigDecimal.class, true); // 6-ConvOpen
356
paymentTable.setColumnClass(i++, BigDecimal.class, false); // 7-Allocated
357
paymentTable.setColumnClass(i++, BigDecimal.class, true); // 8-Multiplier
358

359         //
360
i_payment = multiCurrency.isSelected() ? 7 : 5;
361
362         // Table UI
363
paymentTable.autoSize();
364
365
366         /********************************
367          * Load unpaid Invoices
368          * 1-TrxDate, 2-Value, (3-Currency, 4-InvAmt,)
369          * 5-ConvAmt, 6-ConvOpen, 7-ConvDisc, 8-WriteOff, 9-Applied
370          */

371         data = new Vector();
372         sql = new StringBuffer JavaDoc("SELECT i.DateInvoiced,i.DocumentNo,i.C_Invoice_ID," // 1..3
373
+ "c.ISO_Code,i.GrandTotal*i.MultiplierAP, " // 4..5 Orig Currency
374
+ "C_Currency_Convert(i.GrandTotal*i.MultiplierAP,i.C_Currency_ID,?,null,null,i.AD_Client_ID,i.AD_Org_ID), " // 6 #1 Converted
375
+ "C_Currency_Convert(C_Invoice_Open(C_Invoice_ID),i.C_Currency_ID,?,null,null,i.AD_Client_ID,i.AD_Org_ID)*i.MultiplierAP, " // 7 #2 Converted Open
376
+ "C_Currency_Convert(C_Invoice_Discount" // 8 AllowedDiscount
377
+ "(i.C_Invoice_ID,?),i.C_Currency_ID,?,null,null,i.AD_Client_ID,i.AD_Org_ID)*i.MultiplierAP," // #3, #4
378
+ "i.MultiplierAP "
379             + "FROM C_Invoice_v i" // corrected for CM
380
+ " INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) "
381             + "WHERE i.IsPaid='N' AND i.Processed='Y'"
382             + " AND i.C_BPartner_ID=?"); // #5
383
if (!multiCurrency.isSelected())
384             sql.append(" AND i.C_Currency_ID=?"); // #6
385
sql.append(" ORDER BY i.DateInvoiced, i.DocumentNo");
386         Log.trace(Log.l5_DData, "InvSQL=" + sql.toString());
387         try
388         {
389             PreparedStatement pstmt = DB.prepareStatement(sql.toString());
390             pstmt.setInt(1, m_C_Currency_ID);
391             pstmt.setInt(2, m_C_Currency_ID);
392             pstmt.setTimestamp(3, (Timestamp)dateField.getValue());
393             pstmt.setInt(4, m_C_Currency_ID);
394             pstmt.setInt(5, m_C_BPartner_ID);
395             if (!multiCurrency.isSelected())
396                 pstmt.setInt(6, m_C_Currency_ID);
397             ResultSet rs = pstmt.executeQuery();
398             while (rs.next())
399             {
400                 Vector line = new Vector();
401                 line.add(new Boolean JavaDoc(false)); // 0-Selection
402
line.add(rs.getTimestamp(1)); // 1-TrxDate
403
KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(2));
404                 line.add(pp); // 2-Value
405
if (multiCurrency.isSelected())
406                 {
407                     line.add(rs.getString(4)); // 3-Currency
408
line.add(rs.getBigDecimal(5)); // 4-Orig Amount
409
}
410                 line.add(rs.getBigDecimal(6)); // 3/5-ConvAmt
411
BigDecimal open = rs.getBigDecimal(7);
412                 line.add(open); // 4/6-ConvOpen
413
line.add(rs.getBigDecimal(8)); // 5/7-ConvAllowedDisc
414
line.add(new BigDecimal(0.0)); // 6/8-WriteOff
415
line.add(new BigDecimal(0.0)); // 7/9-Applied
416
line.add(rs.getBigDecimal(9)); // 8/10-Multiplier
417
if (open.compareTo(Env.ZERO) != 0) // add when open <> 0
418
data.add(line);
419             }
420             rs.close();
421             pstmt.close();
422         }
423         catch (SQLException e)
424         {
425             Log.error ("VAllocation.loadBPartner(invoice)", e);
426         }
427
428         // Remove previous listeners
429
invoiceTable.getModel().removeTableModelListener(this);
430         // Header Info
431
columnNames = new Vector();
432         columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
433         columnNames.add(Msg.translate(Env.getCtx(), "Date"));
434         columnNames.add(Msg.translate(Env.getCtx(), "DocumentNo"));
435         if (multiCurrency.isSelected())
436         {
437             columnNames.add(Msg.getMsg(Env.getCtx(), "TrxCurrency"));
438             columnNames.add(Msg.translate(Env.getCtx(), "Amount"));
439         }
440         columnNames.add(Msg.getMsg(Env.getCtx(), "ConvertedAmount"));
441         columnNames.add(Msg.getMsg(Env.getCtx(), "OpenAmt"));
442         columnNames.add(Msg.getMsg(Env.getCtx(), "Discount"));
443         columnNames.add(Msg.getMsg(Env.getCtx(), "WriteOff"));
444         columnNames.add(Msg.getMsg(Env.getCtx(), "AppliedAmt"));
445         columnNames.add(" "); // Multiplier
446

447         // Set Model
448
DefaultTableModel modelI = new DefaultTableModel(data, columnNames);
449         modelI.addTableModelListener(this);
450         invoiceTable.setModel(modelI);
451         //
452
i = 0;
453         invoiceTable.setColumnClass(i++, Boolean JavaDoc.class, false); // 0-Selection
454
invoiceTable.setColumnClass(i++, Timestamp.class, true); // 1-TrxDate
455
invoiceTable.setColumnClass(i++, String JavaDoc.class, true); // 2-Value
456
if (multiCurrency.isSelected())
457         {
458             invoiceTable.setColumnClass(i++, String JavaDoc.class, true); // 3-Currency
459
invoiceTable.setColumnClass(i++, BigDecimal.class, true); // 4-Amt
460
}
461         invoiceTable.setColumnClass(i++, BigDecimal.class, true); // 5-ConvAmt
462
invoiceTable.setColumnClass(i++, BigDecimal.class, true); // 6-ConvAmt Open
463
invoiceTable.setColumnClass(i++, BigDecimal.class, false); // 7-Conv Discount
464
invoiceTable.setColumnClass(i++, BigDecimal.class, false); // 8-Conv WriteOff
465
invoiceTable.setColumnClass(i++, BigDecimal.class, false); // 9-Conv Applied
466
invoiceTable.setColumnClass(i++, BigDecimal.class, true); // 10-Multiplier
467
// Table UI
468
invoiceTable.autoSize();
469
470         i_open = multiCurrency.isSelected() ? 6 : 4;
471         i_discount = multiCurrency.isSelected() ? 7 : 5;
472         i_writeOff = multiCurrency.isSelected() ? 8 : 6;
473         i_applied = multiCurrency.isSelected() ? 9 : 7;
474         i_multiplier = multiCurrency.isSelected() ? 10 : 8;
475
476         // Calculate Totals
477
calculate();
478     } // loadBPartner
479

480
481     /*************************************************************************/
482
483     /**
484      * Action Listener.
485      * - MultiCurrency
486      * - Allocate
487      * @param e event
488      */

489     public void actionPerformed(ActionEvent e)
490     {
491         Log.trace(Log.l3_Util, "VAllocation.actionPerformed");
492         if (e.getSource().equals(multiCurrency))
493             loadBPartner();
494         if (e.getSource().equals(allocateButton))
495         {
496             allocateButton.setEnabled(false);
497             saveData();
498             loadBPartner();
499             allocateButton.setEnabled(true);
500         }
501     } // actionPerformed
502

503     /**
504      * Table Model Listener.
505      * - Recalculate Totals
506      * @param e event
507      */

508     public void tableChanged(TableModelEvent e)
509     {
510         boolean isUpdate = (e.getType() == TableModelEvent.UPDATE);
511         // Not a table update
512
if (!isUpdate)
513         {
514             calculate();
515             return;
516         }
517
518         /**
519          * Setting defaults
520          */

521         if (m_calculating) // Avoid recursive calls
522
return;
523         m_calculating = true;
524         int row = e.getFirstRow();
525         int col = e.getColumn();
526         boolean isInvoice = (e.getSource().equals(invoiceTable.getModel()));
527         Log.trace(Log.l3_Util, "VAllocation.tableChanged Row=" + row + ", Col=" + col + ", InvoiceTable=" + isInvoice);
528
529         // Payments
530
if (!isInvoice)
531         {
532             TableModel payment = paymentTable.getModel();
533             if (col == 0)
534             {
535                 // selected - set payment amount
536
if (((Boolean JavaDoc)payment.getValueAt(row, col)).booleanValue())
537                 {
538                     BigDecimal amount = (BigDecimal)payment.getValueAt(row, i_open); // Open Amount
539
payment.setValueAt(amount, row, i_payment);
540                 }
541                 else // de-selected
542
payment.setValueAt(Env.ZERO, row, i_payment);
543             }
544         }
545
546         // Invoice Selection
547
else if (col == 0)
548         {
549             TableModel invoice = invoiceTable.getModel();
550             // selected - set applied amount
551
if (((Boolean JavaDoc)invoice.getValueAt(row, col)).booleanValue())
552             {
553                 BigDecimal amount = (BigDecimal)invoice.getValueAt(row, i_open); // Open Amount
554
amount = amount.subtract((BigDecimal)invoice.getValueAt(row, i_discount));
555                 invoice.setValueAt(Env.ZERO, row, i_writeOff); // to be sure
556
invoice.setValueAt(amount, row, i_applied);
557             }
558             else // de-selected
559
{
560                 invoice.setValueAt(Env.ZERO, row, i_writeOff);
561                 invoice.setValueAt(Env.ZERO, row, i_applied);
562             }
563             invoiceTable.repaint(); // update r/o
564
}
565
566         // Invoice - Try to balance entry
567
else if (autoCalc.isSelected())
568         {
569             TableModel invoice = invoiceTable.getModel();
570             // if applied entered, adjust writeOff
571
if (col == i_applied)
572             {
573                 BigDecimal amount = (BigDecimal)invoice.getValueAt(row, i_open); // Open Amount
574
amount = amount.subtract((BigDecimal)invoice.getValueAt(row, i_discount));
575                 amount = amount.subtract((BigDecimal)invoice.getValueAt(row, i_applied));
576                 invoice.setValueAt(amount, row, i_writeOff);
577             }
578             else // adjust applied
579
{
580                 BigDecimal amount = (BigDecimal)invoice.getValueAt(row, i_open); // Open Amount
581
amount = amount.subtract((BigDecimal)invoice.getValueAt(row, i_discount));
582                 amount = amount.subtract((BigDecimal)invoice.getValueAt(row, i_writeOff));
583                 invoice.setValueAt(amount, row, i_applied);
584             }
585         }
586
587         m_calculating = false;
588         calculate();
589     } // tableChanged
590

591     /**
592      * Calculate Allocation info
593      */

594     private void calculate ()
595     {
596         Log.trace(Log.l3_Util, "VAllocation.calculate");
597         //
598
DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
599
600         // Payment
601
TableModel payment = paymentTable.getModel();
602         BigDecimal totalPay = new BigDecimal(0.0);
603         int rows = payment.getRowCount();
604         m_noPayments = 0;
605         for (int i = 0; i < rows; i++)
606         {
607             if (((Boolean JavaDoc)payment.getValueAt(i, 0)).booleanValue())
608             {
609                 BigDecimal bd = (BigDecimal)payment.getValueAt(i, i_payment);
610                 totalPay = totalPay.add(bd); // Applied Pay
611
m_noPayments++;
612                 Log.trace(Log.l6_Database, "Payment_" + i + " = " + bd + " - Total=" + totalPay);
613             }
614         }
615         paymentInfo.setText(String.valueOf(m_noPayments) + " - "
616             + Msg.getMsg(Env.getCtx(), "Sum") + " " + format.format(totalPay) + " ");
617
618         // Invoices
619
TableModel invoice = invoiceTable.getModel();
620         BigDecimal totalInv = new BigDecimal(0.0);
621         rows = invoice.getRowCount();
622         m_noInvoices = 0;
623
624         for (int i = 0; i < rows; i++)
625         {
626             if (((Boolean JavaDoc)invoice.getValueAt(i, 0)).booleanValue())
627             {
628                 BigDecimal bd = (BigDecimal)invoice.getValueAt(i, i_applied);
629                 totalInv = totalInv.add(bd); // Applied Inv
630
m_noInvoices++;
631                 Log.trace(Log.l6_Database, "Invoice_" + i + " = " + bd + " - Total=" + totalPay);
632             }
633         }
634         invoiceInfo.setText(String.valueOf(m_noInvoices) + " - "
635             + Msg.getMsg(Env.getCtx(), "Sum") + " " + format.format(totalInv) + " ");
636
637
638         // Set Allocation Currency
639
allocCurrencyLabel.setText(currencyPick.getDisplay());
640         // Difference
641
BigDecimal difference = totalPay.subtract(totalInv);
642         differenceField.setText(format.format(difference));
643         if (difference.compareTo(new BigDecimal(0.0)) == 0)
644             allocateButton.setEnabled(true);
645         else
646             allocateButton.setEnabled(false);
647     } // calculate
648

649     /**
650      * Vetoable Change Listener.
651      * - Business Partner
652      * - Discount
653      * @param e event
654      */

655     public void vetoableChange (PropertyChangeEvent e)
656     {
657         String JavaDoc name = e.getPropertyName();
658         Object JavaDoc value = e.getNewValue();
659         Log.trace(Log.l3_Util, "VAllocation.vetoableChange - " + name + "=" + value);
660         if (value == null)
661             return;
662
663         // BPartner / Currency
664
if (name.equals("C_BPartner_ID"))
665         {
666             bpartnerSearch.setValue(value);
667             m_C_BPartner_ID = ((Integer JavaDoc)value).intValue();
668             loadBPartner();
669         }
670         else if (name.equals("C_Currency_ID"))
671         {
672             m_C_Currency_ID = ((Integer JavaDoc)value).intValue();
673             loadBPartner();
674         }
675         else if (name.equals("Date"))
676             loadBPartner();
677     } // vetoableChange
678

679     /*************************************************************************/
680
681     /**
682      * Save Data
683      */

684     private void saveData()
685     {
686         if (m_noInvoices + m_noPayments == 0)
687             return;
688         Log.trace(Log.l3_Util, "VAllocation.saveData");
689
690         // fixed fields
691
int AD_Client_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_Client_ID");
692         int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_Org_ID");
693         int C_BPartner_ID = m_C_BPartner_ID;
694         int C_Order_ID = 0;
695         int C_CashLine_ID = 0;
696         Timestamp DateTrx = (Timestamp)dateField.getValue();
697         int C_Currency_ID = m_C_Currency_ID;
698         int AllocationNo = 0; // C_Allocation_Seq.NextVal
699
try
700         {
701             CallableStatement cstmt = DB.prepareCall("{? = call C_Allocation_No(?)}");
702             cstmt.registerOutParameter(1, Types.INTEGER);
703             cstmt.setInt(2, AD_Client_ID);
704             cstmt.executeUpdate();
705             AllocationNo = cstmt.getInt(1);
706             cstmt.close();
707         }
708         catch (SQLException e)
709         {
710             Log.error ("VAllocation.saveData - AllocationNo", e);
711         }
712         Log.trace(Log.l4_Data, "Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
713             + ", BPartner=" + C_BPartner_ID + ", AllocationNo=" + AllocationNo + ", Date=" + DateTrx);
714
715         /**
716          * Generation of allocations: amount/discount/writeOff
717          * - if there is one payment -- one line per invoice is generated
718          * with both the Invoice and Payment reference
719          * Pay=80 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#1
720          * or
721          * Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#1
722          * Pay=160 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#1 Inv#2
723          *
724          * - if there are multiple payment lines -- the amounts are allocated
725          * starting with the first payment and payment
726          * Pay=60 Inv=100 Disc=10 WOff=10 => 60/10/10 Pay#1 Inv#1
727          * Pay=100 Inv=100 Disc=10 WOff=10 => 20/0/0 Pay#2 Inv#1
728          * Pay=100 Inv=100 Disc=10 WOff=10 => 80/10/10 Pay#2 Inv#2
729          *
730          * - if you apply a credit memo to an invoice
731          * Inv=10 Disc=0 WOff=0 => 10/0/0 Inv#1
732          * Inv=-10 Disc=0 WOff=0 => -10/0/0 Inv#2
733          *
734          * - if you want to write off a (partial) invoice without applying,
735          * enter zero in applied
736          * Inv=10 Disc=1 WOff=9 => 0/1/9 Inv#1
737          * Issues
738          * - you cannot write-off a payment
739          */

740
741         // Payment - Loop and add them to paymentList/amountList
742
int rows = paymentTable.getRowCount();
743         TableModel payment = paymentTable.getModel();
744         ArrayList paymentList = new ArrayList(rows);
745         ArrayList amountList = new ArrayList(rows);
746         ArrayList multiplierList = new ArrayList(rows);
747         for (int i = 0; i < rows; i++)
748         {
749             // Payment line is selected
750
if (((Boolean JavaDoc)payment.getValueAt(i, 0)).booleanValue())
751             {
752                 KeyNamePair pp = (KeyNamePair)payment.getValueAt(i, 2); // Value
753
// Payment variables
754
int C_Payment_ID = pp.getKey();
755                 paymentList.add(new Integer JavaDoc(C_Payment_ID));
756                 //
757
BigDecimal PaymentAmt = (BigDecimal)payment.getValueAt(i, i_payment); // Applied Payment
758
amountList.add(PaymentAmt);
759                 BigDecimal Multiplier = (BigDecimal)payment.getValueAt(i, i_payment+1);
760                 multiplierList.add(Multiplier);
761                 Log.trace(Log.l6_Database, "Payment - ID=" + C_Payment_ID + " - PaymentAmt=" + PaymentAmt + " " + Multiplier);
762             }
763         }
764         Log.trace(Log.l4_Data, "Number of Payments=" + paymentList.size());
765
766         // Invoices - Loop and generate alloctions
767
rows = invoiceTable.getRowCount();
768         TableModel invoice = invoiceTable.getModel();
769         BigDecimal TotalAppliedAmt = Env.ZERO;
770         for (int i = 0; i < rows; i++)
771         {
772             // Invoice line is selected
773
if (((Boolean JavaDoc)invoice.getValueAt(i, 0)).booleanValue())
774             {
775                 KeyNamePair pp = (KeyNamePair)invoice.getValueAt(i, 2); // Value
776
// Invoice variables
777
int C_Invoice_ID = pp.getKey();
778                 BigDecimal AppliedAmt = (BigDecimal)invoice.getValueAt(i, i_applied);
779                 BigDecimal AppliedMultiplier = (BigDecimal)invoice.getValueAt(i, i_multiplier);
780                 BigDecimal AppliedAbs = AppliedAmt.multiply(AppliedMultiplier);
781                 // semi-fixed fields (reset after first invoice)
782
BigDecimal DiscountAmt = (BigDecimal)invoice.getValueAt(i, i_discount);
783                 DiscountAmt = DiscountAmt.multiply(AppliedMultiplier);
784                 BigDecimal WriteOffAmt = (BigDecimal)invoice.getValueAt(i, i_writeOff);
785                 WriteOffAmt = WriteOffAmt.multiply(AppliedMultiplier);
786
787                 Log.trace(Log.l4_Data, "Invoice #" + i + " - AppliedAmt=" + AppliedAmt + " -> " + AppliedAbs);
788                 // loop through all payments until invoice applied
789
int noPayments = 0;
790                 for (int j = 0; j < paymentList.size() && AppliedAmt.compareTo(Env.ZERO) != 0; j++)
791                 {
792                     int C_Payment_ID = ((Integer JavaDoc)paymentList.get(j)).intValue();
793                     BigDecimal PaymentAmt = (BigDecimal)amountList.get(j);
794                     BigDecimal PaymentMultiplier = (BigDecimal)multiplierList.get(j);
795                     BigDecimal PaymentAbs = PaymentAmt.multiply(PaymentMultiplier);
796                     if (PaymentAbs.compareTo(Env.ZERO) != 0)
797                     {
798                         Log.trace(Log.l4_Data, ".. with payment #" + j + ", Amt=" + PaymentAmt + " -> " + PaymentAbs);
799                         noPayments++;
800                         // use the lesser of Payment Amt and Invoice Applied Amt
801
BigDecimal amount = AppliedAbs.min(PaymentAbs);
802                         if (PaymentAbs.compareTo(Env.ZERO) < 0)
803                             amount = AppliedAbs;
804                         //
805
Log.trace(Log.l5_DData, "Payment=" + C_Payment_ID + ", Invoice=" + C_Invoice_ID
806                             + ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);
807
808                         int C_Allocation_ID = MAllocation.createAllocation(Env.getCtx(), m_WindowNo,
809                             AD_Client_ID, AD_Org_ID, C_BPartner_ID,
810                             0, C_Invoice_ID, C_Payment_ID, 0,
811                             AllocationNo, C_Currency_ID, DateTrx, true,
812                             amount, DiscountAmt, WriteOffAmt);
813
814                         // Apply Discounts and WriteOff only first time
815
DiscountAmt = Env.ZERO;
816                         WriteOffAmt = Env.ZERO;
817                         // subtract amount from Payment/Invoice
818
AppliedAmt = AppliedAmt.subtract(amount.multiply(PaymentMultiplier));
819                         PaymentAmt = PaymentAmt.subtract(amount.multiply(PaymentMultiplier));
820                         Log.trace(Log.l6_Database, "Allocation Amount=" + amount + " - Remaining Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);
821                         amountList.set(j, PaymentAmt); // update
822
}
823                 }
824                 // No Payments allocated
825
if (noPayments == 0)
826                 {
827                     int C_Payment_ID = 0;
828                     Log.trace(Log.l4_Data, " ... no payment - TotalApplied=" + TotalAppliedAmt);
829                     // Create Allocation
830
Log.trace(Log.l5_DData, "Payment=" + C_Payment_ID + ", Invoice=" + C_Invoice_ID
831                         + ", Amount=" + AppliedAbs + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);
832
833                     int C_Allocation_ID = MAllocation.createAllocation(Env.getCtx(), m_WindowNo,
834                         AD_Client_ID, AD_Org_ID, C_BPartner_ID,
835                         0, C_Invoice_ID, C_Payment_ID, 0,
836                         AllocationNo, C_Currency_ID, DateTrx, true,
837                         AppliedAbs, DiscountAmt, WriteOffAmt);
838                     if (C_Allocation_ID == 0)
839                         Log.error("VAllocation.saveData - Allocation not written - Invoice=" + C_Invoice_ID);
840
841                     Log.trace(Log.l6_Database, "Allocation Amount=" + AppliedAbs);
842                 }
843                 TotalAppliedAmt = TotalAppliedAmt.add(AppliedAmt);
844                 Log.trace(Log.l4_Data, "TotalRemaining=" + TotalAppliedAmt);
845
846                 // Test/Set IsPaid for Invoice
847
String JavaDoc sql = "UPDATE C_Invoice SET IsPaid='Y' "
848                     + "WHERE C_Invoice_Paid(C_Invoice_ID, C_Currency_ID, 1)=GrandTotal"
849                     + " AND C_Invoice_ID=" + C_Invoice_ID;
850                 int no = DB.executeUpdate(sql);
851                 Log.trace(Log.l4_Data, "Invoice #" + i + (no==0 ? " not" : " is") + " paid");
852             } // invoice selected
853
} // invoice loop
854

855         if (TotalAppliedAmt.compareTo(Env.ZERO) != 0)
856             Log.error("VAllocation.saveData - Remaining TotalAppliedAmt=" + TotalAppliedAmt);
857
858         // Test/Set Payment is fully allocated
859
for (int i = 0; i < paymentList.size(); i++)
860         {
861             String JavaDoc sql = "UPDATE C_Payment SET IsAllocated='Y' "
862                 + "WHERE C_Payment_Allocated(C_Payment_ID, C_Currency_ID)=PayAmt"
863                 + " AND C_Payment_ID=" + ((Integer JavaDoc)paymentList.get(i)).intValue();
864             int no = DB.executeUpdate(sql);
865             Log.trace(Log.l4_Data, "Payment #" + i + (no==0 ? " not" : " is") + " fully allocated");
866         }
867         paymentList.clear();
868         amountList.clear();
869     } // saveData
870

871 } // VAllocation
872
Popular Tags