OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 177 | Rev 182 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
18 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.erp.core.common.ui;
15
 
93 ilm 16
import org.openconcerto.erp.core.finance.accounting.model.Currency;
17
import org.openconcerto.erp.core.finance.accounting.model.CurrencyConverter;
18 ilm 18
import org.openconcerto.sql.model.SQLField;
19
import org.openconcerto.sql.model.SQLRowValues;
20
import org.openconcerto.sql.view.list.IListe;
21
import org.openconcerto.sql.view.list.ITableModel;
177 ilm 22
import org.openconcerto.sql.view.list.ListSQLLine;
61 ilm 23
import org.openconcerto.sql.view.list.SQLTableModelColumn;
18 ilm 24
import org.openconcerto.ui.DefaultGridBagConstraints;
25
import org.openconcerto.ui.JLabelBold;
177 ilm 26
import org.openconcerto.utils.TableSorter;
18 ilm 27
import org.openconcerto.utils.Tuple2;
28
 
29
import java.awt.GridBagConstraints;
30
import java.awt.GridBagLayout;
19 ilm 31
import java.beans.PropertyChangeListener;
61 ilm 32
import java.math.BigDecimal;
33
import java.math.MathContext;
34
import java.text.DecimalFormat;
35
import java.util.ArrayList;
18 ilm 36
import java.util.HashMap;
37
import java.util.List;
38
import java.util.Map;
39
 
40
import javax.swing.JLabel;
41
import javax.swing.JPanel;
61 ilm 42
import javax.swing.SwingConstants;
19 ilm 43
import javax.swing.event.EventListenerList;
180 ilm 44
import javax.swing.event.ListSelectionEvent;
45
import javax.swing.event.ListSelectionListener;
18 ilm 46
import javax.swing.event.TableModelEvent;
47
import javax.swing.event.TableModelListener;
177 ilm 48
import javax.swing.table.TableModel;
18 ilm 49
 
50
public class IListTotalPanel extends JPanel {
93 ilm 51
    CurrencyConverter cc = new CurrencyConverter();
18 ilm 52
 
61 ilm 53
    public enum Type {
54
        // Pourcentage moyen d'une colonne
55
        MOYENNE_POURCENT,
56
        // Moyenne d'une colonne
57
        MOYENNE_DEVISE,
58
        // Somme total d'une colonne
59
        SOMME,
151 ilm 60
        // Somme total d'une colonne
61
        SOMME_QTE,
61 ilm 62
        // Marge en pourcentage requiert dans la liste la colonne achat en premier et vente en
63
        // deuxieme
90 ilm 64
        MOYENNE_MARGE,
65
        // Requiert le field TTC
93 ilm 66
        AVANCEMENT_TTC,
67
        // TOTAL DES LIGNES
68
        COUNT;
61 ilm 69
    };
70
 
71
    DecimalFormat decimalFormat = new DecimalFormat("##,##0.00");
72
 
19 ilm 73
    EventListenerList loadingListener = new EventListenerList();
18 ilm 74
    private final IListe list;
61 ilm 75
    private final Map<SQLTableModelColumn, JLabel> map = new HashMap<SQLTableModelColumn, JLabel>();
18 ilm 76
 
77
    public IListTotalPanel(IListe l, final List<SQLField> listField) {
61 ilm 78
        this(l, initListe(l, listField), null, null);
18 ilm 79
    }
80
 
61 ilm 81
    public IListTotalPanel(IListe l, final List<SQLField> listField, String title) {
82
        this(l, initListe(l, listField), null, title);
83
    }
84
 
85
    public static List<Tuple2<? extends SQLTableModelColumn, Type>> initListe(IListe iL, List<SQLField> l) {
86
        List<Tuple2<? extends SQLTableModelColumn, Type>> lFinal = new ArrayList<Tuple2<? extends SQLTableModelColumn, Type>>();
87
 
88
        for (SQLField field : l) {
177 ilm 89
            final SQLTableModelColumn col = iL.getSource().getColumn(field);
90
            if (col == null)
91
                throw new IllegalArgumentException("No column with just " + field + " : " + iL.getSource().getColumns());
92
            lFinal.add(Tuple2.create(col, Type.SOMME));
61 ilm 93
        }
94
        return lFinal;
95
    }
96
 
93 ilm 97
    public IListTotalPanel(IListe l, final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, String title) {
180 ilm 98
        this(l, listField, filters, null, title, false);
93 ilm 99
    }
100
 
180 ilm 101
    public IListTotalPanel(IListe l, final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, final List<Tuple2<SQLField, ?>> filtersNot,
102
            String title) {
103
        this(l, listField, filters, filtersNot, title, false);
104
    }
105
 
106
    private final boolean onSelection;
107
 
18 ilm 108
    /**
109
     *
110
     * @param l
111
     * @param listField Liste des fields à totaliser
112
     * @param filters filtre ex : Tuple((SQLField)NATEXIER,(Boolean)FALSE)
113
     */
93 ilm 114
    public IListTotalPanel(IListe l, final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, final List<Tuple2<SQLField, ?>> filtersNot,
180 ilm 115
            String title, boolean onSelection) {
18 ilm 116
        super(new GridBagLayout());
117
        this.list = l;
61 ilm 118
        this.setOpaque(false);
180 ilm 119
        this.onSelection = onSelection;
18 ilm 120
        GridBagConstraints c = new DefaultGridBagConstraints();
121
        c.gridx = GridBagConstraints.RELATIVE;
122
        c.weightx = 0;
123
        if (title != null && title.trim().length() > 0) {
73 ilm 124
            JLabel sep = new JLabel(title);
18 ilm 125
            c.weightx = 1;
126
            c.gridwidth = GridBagConstraints.REMAINDER;
127
            this.add(sep, c);
128
            c.gridy++;
129
            c.gridwidth = 1;
130
        }
131
        // Filtre
61 ilm 132
        for (Tuple2<? extends SQLTableModelColumn, Type> field2 : listField) {
18 ilm 133
            c.weightx = 0;
73 ilm 134
            final SQLTableModelColumn col = field2.get0();
135
            if (col == null) {
136
                throw new IllegalStateException("null SQLTableModelColumn in " + listField);
137
            }
138
            final JLabelBold comp = new JLabelBold(col.getName());
61 ilm 139
            comp.setHorizontalAlignment(SwingConstants.RIGHT);
140
            this.add(comp, c);
18 ilm 141
            JLabelBold textField = new JLabelBold("0");
61 ilm 142
            textField.setHorizontalAlignment(SwingConstants.RIGHT);
143
            this.map.put(field2.get0(), textField);
18 ilm 144
            c.weightx = 1;
145
            this.add(textField, c);
73 ilm 146
            c.weightx = 0;
90 ilm 147
            if (field2.get1() == Type.SOMME || field2.get1() == Type.MOYENNE_DEVISE || field2.get1() == Type.AVANCEMENT_TTC) {
93 ilm 148
                this.add(new JLabelBold(Currency.getSymbol(cc.getCompanyCurrencyCode())), c);
61 ilm 149
            } else if (field2.get1() == Type.MOYENNE_POURCENT || field2.get1() == Type.MOYENNE_MARGE) {
150
                this.add(new JLabelBold("%"), c);
151
            }
18 ilm 152
            c.gridy++;
153
        }
154
 
180 ilm 155
        if (this.onSelection) {
156
            this.list.getJTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
177 ilm 157
 
180 ilm 158
                @Override
159
                public void valueChanged(ListSelectionEvent e) {
177 ilm 160
 
180 ilm 161
                    final List<ListSQLLine> listLines = list.getSelectedLines();
162
                    for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
163
                        if (field.get1() == Type.COUNT) {
164
                            map.get(field.get0()).setText(String.valueOf(listLines.size()));
165
                        }
166
                    }
167
                    computeValues(listField, filters, filtersNot, listLines);
168
                }
169
            });
170
        } else {
177 ilm 171
 
180 ilm 172
            this.list.addListener(new TableModelListener() {
173
 
174
                @Override
175
                public void tableChanged(TableModelEvent e) {
176
                    final TableModel model = (TableModel) e.getSource();
177
                    final ITableModel sqlModel;
178
                    if (model instanceof ITableModel)
179
                        sqlModel = (ITableModel) model;
180
                    else
181
                        sqlModel = (ITableModel) ((TableSorter) model).getTableModel();
182
 
183
                    final List<ListSQLLine> listLines = new ArrayList<>();
184
                    for (int i = 0; i < sqlModel.getRowCount(); i++) {
185
                        listLines.add(sqlModel.getRow(i));
93 ilm 186
                    }
180 ilm 187
                    for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
188
                        if (field.get1() == Type.COUNT) {
189
                            map.get(field.get0()).setText(String.valueOf(model.getRowCount()));
190
                        }
191
                    }
192
                    computeValues(listField, filters, filtersNot, listLines);
93 ilm 193
                }
61 ilm 194
 
180 ilm 195
            });
196
        }
197
    }
18 ilm 198
 
180 ilm 199
    public void fireUpdated() {
200
        for (PropertyChangeListener l : this.loadingListener.getListeners(PropertyChangeListener.class)) {
201
            l.propertyChange(null);
202
        }
203
    }
18 ilm 204
 
180 ilm 205
    public void addListener(PropertyChangeListener l) {
206
        this.loadingListener.add(PropertyChangeListener.class, l);
207
    }
18 ilm 208
 
180 ilm 209
    private Object getValueAt(final ListSQLLine line, final SQLTableModelColumn col, final List<SQLTableModelColumn> columns) {
210
        final int indexOf = columns.indexOf(col);
211
        final Object res = line.getValueAt(indexOf);
212
        if (res == null)
213
            throw new IllegalStateException("Null value for " + col + " in " + line);
214
        return res;
215
    }
61 ilm 216
 
180 ilm 217
    private void computeValues(final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, final List<Tuple2<SQLField, ?>> filtersNot,
218
            final List<ListSQLLine> listLines) {
219
        Map<SQLTableModelColumn, BigDecimal> mapTotal = new HashMap<SQLTableModelColumn, BigDecimal>();
220
        Map<SQLTableModelColumn, Double> mapPourcent = new HashMap<SQLTableModelColumn, Double>();
221
        Map<SQLTableModelColumn, Integer> mapPourcentSize = new HashMap<SQLTableModelColumn, Integer>();
18 ilm 222
 
180 ilm 223
        for (ListSQLLine line : listLines) {
93 ilm 224
 
180 ilm 225
            final SQLRowValues rowAt = line.getRow();
226
            final List<SQLTableModelColumn> columns = line.getColumns().getColumns();
61 ilm 227
 
180 ilm 228
            for (final Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
229
                final Type type = field.get1();
61 ilm 230
 
180 ilm 231
                if (type == Type.MOYENNE_POURCENT) {
232
                    final Double n2 = (Double) getValueAt(line, field.get0(), columns);
61 ilm 233
 
180 ilm 234
                    boolean in = true;
90 ilm 235
 
180 ilm 236
                    if (filters != null) {
237
                        for (Tuple2<SQLField, ?> tuple2 : filters) {
238
                            in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
239
                        }
240
                    }
90 ilm 241
 
180 ilm 242
                    if (filtersNot != null) {
243
                        for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
244
                            in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
245
                        }
246
                    }
90 ilm 247
 
180 ilm 248
                    if (in) {
90 ilm 249
 
180 ilm 250
                        if (mapPourcent.get(field.get0()) == null) {
251
                            mapPourcent.put(field.get0(), n2);
252
                        } else {
253
                            mapPourcent.put(field.get0(), n2 + mapPourcent.get(field.get0()));
254
                        }
90 ilm 255
 
180 ilm 256
                        if (mapPourcentSize.get(field.get0()) == null) {
257
                            mapPourcentSize.put(field.get0(), 1);
258
                        } else {
259
                            mapPourcentSize.put(field.get0(), mapPourcentSize.get(field.get0()).intValue() + 1);
260
                        }
61 ilm 261
 
180 ilm 262
                    }
263
                } else if (type == Type.AVANCEMENT_TTC) {
61 ilm 264
 
180 ilm 265
                    BigDecimal n = mapTotal.get(field.get0());
266
                    BigDecimal ttc = BigDecimal.valueOf(line.getRow().getObjectAs("T_TTC", Number.class).doubleValue());
61 ilm 267
 
180 ilm 268
                    BigDecimal av = BigDecimal.valueOf(((Number) getValueAt(line, field.get0(), columns)).doubleValue());
61 ilm 269
 
180 ilm 270
                    boolean in = true;
271
 
272
                    if (filters != null) {
273
                        for (Tuple2<SQLField, ?> tuple2 : filters) {
274
                            in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
18 ilm 275
                        }
276
                    }
180 ilm 277
                    if (filtersNot != null) {
278
                        for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
279
                            in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
280
                        }
281
                    }
18 ilm 282
 
180 ilm 283
                    if (in) {
284
                        if (n == null) {
285
                            mapTotal.put(field.get0(), ttc.multiply(av).movePointLeft(2));
61 ilm 286
                        } else {
180 ilm 287
                            mapTotal.put(field.get0(), n.add(ttc.multiply(av).movePointLeft(2)));
61 ilm 288
                        }
180 ilm 289
                    }
290
                } else if (type != Type.MOYENNE_MARGE && type != Type.COUNT) {
291
                    BigDecimal n = mapTotal.get(field.get0());
292
 
293
                    final Object value = getValueAt(line, field.get0(), columns);
294
                    final BigDecimal n2 = BigDecimal.valueOf(((Number) value).doubleValue());
295
 
296
                    boolean in = true;
297
 
298
                    if (filters != null) {
299
                        for (Tuple2<SQLField, ?> tuple2 : filters) {
300
                            in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
61 ilm 301
                        }
180 ilm 302
                    }
303
                    if (filtersNot != null) {
304
                        for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
305
                            in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
306
                        }
307
                    }
308
 
309
                    if (in) {
310
                        if (n == null) {
311
                            mapTotal.put(field.get0(), n2);
61 ilm 312
                        } else {
180 ilm 313
                            mapTotal.put(field.get0(), n.add(n2));
61 ilm 314
                        }
18 ilm 315
                    }
316
                }
317
            }
180 ilm 318
        }
19 ilm 319
 
180 ilm 320
        for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
321
            if (field.get1() == Type.MOYENNE_MARGE) {
322
 
323
                BigDecimal totalVT = mapTotal.get(listField.get(0).get0());
324
                BigDecimal totalHA = mapTotal.get(listField.get(1).get0());
325
                if (totalHA != null && totalVT != null && totalVT.longValue() != 0) {
326
                    map.get(field.get0()).setText(decimalFormat.format(totalVT.subtract(totalHA).divide(totalVT, MathContext.DECIMAL32).doubleValue() * 100.0D));
327
                } else {
328
                    map.get(field.get0()).setText(decimalFormat.format(0));
329
                }
330
            } else if (field.get1() == Type.MOYENNE_POURCENT) {
331
                Double l = mapPourcent.get(field.get0());
332
                Integer d = mapPourcentSize.get(field.get0());
333
                if (l != null && d != null && d != 0) {
334
                    map.get(field.get0()).setText(decimalFormat.format(l / (double) d));
335
                } else {
336
                    map.get(field.get0()).setText(decimalFormat.format(0));
337
                }
338
            } else if (field.get1() != Type.COUNT) {
339
                BigDecimal l = mapTotal.get(field.get0());
340
                if (l != null) {
341
                    map.get(field.get0()).setText(decimalFormat.format(l.doubleValue()));
342
                } else {
343
                    map.get(field.get0()).setText(decimalFormat.format(0));
344
                }
345
            }
19 ilm 346
        }
180 ilm 347
        fireUpdated();
19 ilm 348
    }
18 ilm 349
}