OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 151 | Rev 180 | 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;
18 ilm 44
import javax.swing.event.TableModelEvent;
45
import javax.swing.event.TableModelListener;
177 ilm 46
import javax.swing.table.TableModel;
18 ilm 47
 
48
public class IListTotalPanel extends JPanel {
93 ilm 49
    CurrencyConverter cc = new CurrencyConverter();
18 ilm 50
 
61 ilm 51
    public enum Type {
52
        // Pourcentage moyen d'une colonne
53
        MOYENNE_POURCENT,
54
        // Moyenne d'une colonne
55
        MOYENNE_DEVISE,
56
        // Somme total d'une colonne
57
        SOMME,
151 ilm 58
        // Somme total d'une colonne
59
        SOMME_QTE,
61 ilm 60
        // Marge en pourcentage requiert dans la liste la colonne achat en premier et vente en
61
        // deuxieme
90 ilm 62
        MOYENNE_MARGE,
63
        // Requiert le field TTC
93 ilm 64
        AVANCEMENT_TTC,
65
        // TOTAL DES LIGNES
66
        COUNT;
61 ilm 67
    };
68
 
69
    DecimalFormat decimalFormat = new DecimalFormat("##,##0.00");
70
 
19 ilm 71
    EventListenerList loadingListener = new EventListenerList();
18 ilm 72
    private final IListe list;
61 ilm 73
    private final Map<SQLTableModelColumn, JLabel> map = new HashMap<SQLTableModelColumn, JLabel>();
18 ilm 74
 
75
    public IListTotalPanel(IListe l, final List<SQLField> listField) {
61 ilm 76
        this(l, initListe(l, listField), null, null);
18 ilm 77
    }
78
 
61 ilm 79
    public IListTotalPanel(IListe l, final List<SQLField> listField, String title) {
80
        this(l, initListe(l, listField), null, title);
81
    }
82
 
83
    public static List<Tuple2<? extends SQLTableModelColumn, Type>> initListe(IListe iL, List<SQLField> l) {
84
        List<Tuple2<? extends SQLTableModelColumn, Type>> lFinal = new ArrayList<Tuple2<? extends SQLTableModelColumn, Type>>();
85
 
86
        for (SQLField field : l) {
177 ilm 87
            final SQLTableModelColumn col = iL.getSource().getColumn(field);
88
            if (col == null)
89
                throw new IllegalArgumentException("No column with just " + field + " : " + iL.getSource().getColumns());
90
            lFinal.add(Tuple2.create(col, Type.SOMME));
61 ilm 91
        }
92
        return lFinal;
93
    }
94
 
93 ilm 95
    public IListTotalPanel(IListe l, final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, String title) {
96
        this(l, listField, filters, null, title);
97
    }
98
 
18 ilm 99
    /**
100
     *
101
     * @param l
102
     * @param listField Liste des fields à totaliser
103
     * @param filters filtre ex : Tuple((SQLField)NATEXIER,(Boolean)FALSE)
104
     */
93 ilm 105
    public IListTotalPanel(IListe l, final List<Tuple2<? extends SQLTableModelColumn, Type>> listField, final List<Tuple2<SQLField, ?>> filters, final List<Tuple2<SQLField, ?>> filtersNot,
106
            String title) {
18 ilm 107
        super(new GridBagLayout());
108
        this.list = l;
61 ilm 109
        this.setOpaque(false);
18 ilm 110
 
111
        GridBagConstraints c = new DefaultGridBagConstraints();
112
        c.gridx = GridBagConstraints.RELATIVE;
113
        c.weightx = 0;
114
        if (title != null && title.trim().length() > 0) {
73 ilm 115
            JLabel sep = new JLabel(title);
18 ilm 116
            c.weightx = 1;
117
            c.gridwidth = GridBagConstraints.REMAINDER;
118
            this.add(sep, c);
119
            c.gridy++;
120
            c.gridwidth = 1;
121
        }
122
        // Filtre
61 ilm 123
        for (Tuple2<? extends SQLTableModelColumn, Type> field2 : listField) {
18 ilm 124
            c.weightx = 0;
73 ilm 125
            final SQLTableModelColumn col = field2.get0();
126
            if (col == null) {
127
                throw new IllegalStateException("null SQLTableModelColumn in " + listField);
128
            }
129
            final JLabelBold comp = new JLabelBold(col.getName());
61 ilm 130
            comp.setHorizontalAlignment(SwingConstants.RIGHT);
131
            this.add(comp, c);
18 ilm 132
            JLabelBold textField = new JLabelBold("0");
61 ilm 133
            textField.setHorizontalAlignment(SwingConstants.RIGHT);
134
            this.map.put(field2.get0(), textField);
18 ilm 135
            c.weightx = 1;
136
            this.add(textField, c);
73 ilm 137
            c.weightx = 0;
90 ilm 138
            if (field2.get1() == Type.SOMME || field2.get1() == Type.MOYENNE_DEVISE || field2.get1() == Type.AVANCEMENT_TTC) {
93 ilm 139
                this.add(new JLabelBold(Currency.getSymbol(cc.getCompanyCurrencyCode())), c);
61 ilm 140
            } else if (field2.get1() == Type.MOYENNE_POURCENT || field2.get1() == Type.MOYENNE_MARGE) {
141
                this.add(new JLabelBold("%"), c);
142
            }
18 ilm 143
            c.gridy++;
144
        }
145
 
146
        this.list.addListener(new TableModelListener() {
177 ilm 147
 
148
            private Object getValueAt(final ListSQLLine line, final SQLTableModelColumn col, final List<SQLTableModelColumn> columns) {
149
                final int indexOf = columns.indexOf(col);
150
                final Object res = line.getValueAt(indexOf);
151
                if (res == null)
152
                    throw new IllegalStateException("Null value for " + col + " in " + line);
153
                return res;
154
            }
155
 
18 ilm 156
            @Override
157
            public void tableChanged(TableModelEvent e) {
177 ilm 158
                final TableModel model = (TableModel) e.getSource();
159
                final ITableModel sqlModel;
160
                if (model instanceof ITableModel)
161
                    sqlModel = (ITableModel) model;
162
                else
163
                    sqlModel = (ITableModel) ((TableSorter) model).getTableModel();
164
 
61 ilm 165
                Map<SQLTableModelColumn, BigDecimal> mapTotal = new HashMap<SQLTableModelColumn, BigDecimal>();
166
                Map<SQLTableModelColumn, Double> mapPourcent = new HashMap<SQLTableModelColumn, Double>();
167
                Map<SQLTableModelColumn, Integer> mapPourcentSize = new HashMap<SQLTableModelColumn, Integer>();
93 ilm 168
                for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
169
                    if (field.get1() == Type.COUNT) {
177 ilm 170
                        map.get(field.get0()).setText(String.valueOf(model.getRowCount()));
93 ilm 171
                    }
172
                }
61 ilm 173
 
177 ilm 174
                for (int i = 0; i < model.getRowCount(); i++) {
175
                    final ListSQLLine line = sqlModel.getRow(i);
176
                    final SQLRowValues rowAt = line.getRow();
177
                    final List<SQLTableModelColumn> columns = line.getColumns().getColumns();
18 ilm 178
 
177 ilm 179
                    for (final Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
180
                        final Type type = field.get1();
18 ilm 181
 
177 ilm 182
                        if (type == Type.MOYENNE_POURCENT) {
183
                            final Double n2 = (Double) getValueAt(line, field.get0(), columns);
18 ilm 184
 
61 ilm 185
                            boolean in = true;
186
 
187
                            if (filters != null) {
188
                                for (Tuple2<SQLField, ?> tuple2 : filters) {
189
                                    in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
190
                                }
18 ilm 191
                            }
192
 
93 ilm 193
                            if (filtersNot != null) {
194
                                for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
195
                                    in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
196
                                }
197
                            }
198
 
61 ilm 199
                            if (in) {
200
 
201
                                if (mapPourcent.get(field.get0()) == null) {
202
                                    mapPourcent.put(field.get0(), n2);
203
                                } else {
204
                                    mapPourcent.put(field.get0(), n2 + mapPourcent.get(field.get0()));
205
                                }
206
 
207
                                if (mapPourcentSize.get(field.get0()) == null) {
208
                                    mapPourcentSize.put(field.get0(), 1);
209
                                } else {
210
                                    mapPourcentSize.put(field.get0(), mapPourcentSize.get(field.get0()).intValue() + 1);
211
                                }
212
 
18 ilm 213
                            }
177 ilm 214
                        } else if (type == Type.AVANCEMENT_TTC) {
90 ilm 215
 
216
                            BigDecimal n = mapTotal.get(field.get0());
177 ilm 217
                            BigDecimal ttc = BigDecimal.valueOf(line.getRow().getObjectAs("T_TTC", Number.class).doubleValue());
90 ilm 218
 
177 ilm 219
                            BigDecimal av = BigDecimal.valueOf(((Number) getValueAt(line, field.get0(), columns)).doubleValue());
90 ilm 220
 
221
                            boolean in = true;
222
 
223
                            if (filters != null) {
224
                                for (Tuple2<SQLField, ?> tuple2 : filters) {
225
                                    in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
226
                                }
227
                            }
93 ilm 228
                            if (filtersNot != null) {
229
                                for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
230
                                    in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
231
                                }
232
                            }
90 ilm 233
 
234
                            if (in) {
235
                                if (n == null) {
236
                                    mapTotal.put(field.get0(), ttc.multiply(av).movePointLeft(2));
237
                                } else {
238
                                    mapTotal.put(field.get0(), n.add(ttc.multiply(av).movePointLeft(2)));
239
                                }
240
                            }
177 ilm 241
                        } else if (type != Type.MOYENNE_MARGE && type != Type.COUNT) {
61 ilm 242
                            BigDecimal n = mapTotal.get(field.get0());
243
 
177 ilm 244
                            final Object value = getValueAt(line, field.get0(), columns);
245
                            final BigDecimal n2 = BigDecimal.valueOf(((Number) value).doubleValue());
61 ilm 246
 
247
                            boolean in = true;
248
 
249
                            if (filters != null) {
250
                                for (Tuple2<SQLField, ?> tuple2 : filters) {
251
                                    in = in && rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
252
                                }
253
                            }
93 ilm 254
                            if (filtersNot != null) {
255
                                for (Tuple2<SQLField, ?> tuple2 : filtersNot) {
256
                                    in = in && !rowAt.getObject(tuple2.get0().getName()).equals(tuple2.get1());
257
                                }
258
                            }
61 ilm 259
 
260
                            if (in) {
261
                                if (n == null) {
262
                                    mapTotal.put(field.get0(), n2);
263
                                } else {
264
                                    mapTotal.put(field.get0(), n.add(n2));
265
                                }
266
                            }
18 ilm 267
                        }
268
                    }
269
                }
270
 
61 ilm 271
                for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
272
                    if (field.get1() == Type.MOYENNE_MARGE) {
273
 
274
                        BigDecimal totalVT = mapTotal.get(listField.get(0).get0());
275
                        BigDecimal totalHA = mapTotal.get(listField.get(1).get0());
276
                        if (totalHA != null && totalVT != null && totalVT.longValue() != 0) {
277
                            map.get(field.get0()).setText(decimalFormat.format(totalVT.subtract(totalHA).divide(totalVT, MathContext.DECIMAL32).doubleValue() * 100.0D));
278
                        } else {
279
                            map.get(field.get0()).setText(decimalFormat.format(0));
280
                        }
281
                    } else if (field.get1() == Type.MOYENNE_POURCENT) {
282
                        Double l = mapPourcent.get(field.get0());
283
                        Integer d = mapPourcentSize.get(field.get0());
284
                        if (l != null && d != null && d != 0) {
285
                            map.get(field.get0()).setText(decimalFormat.format(l / (double) d));
286
                        } else {
287
                            map.get(field.get0()).setText(decimalFormat.format(0));
288
                        }
93 ilm 289
                    } else if (field.get1() != Type.COUNT) {
61 ilm 290
                        BigDecimal l = mapTotal.get(field.get0());
291
                        if (l != null) {
292
                            map.get(field.get0()).setText(decimalFormat.format(l.doubleValue()));
293
                        } else {
294
                            map.get(field.get0()).setText(decimalFormat.format(0));
295
                        }
18 ilm 296
                    }
297
                }
19 ilm 298
                fireUpdated();
18 ilm 299
            }
300
        });
301
    }
19 ilm 302
 
303
    public void fireUpdated() {
304
        for (PropertyChangeListener l : this.loadingListener.getListeners(PropertyChangeListener.class)) {
305
            l.propertyChange(null);
306
        }
307
    }
308
 
309
    public void addListener(PropertyChangeListener l) {
310
        this.loadingListener.add(PropertyChangeListener.class, l);
311
    }
312
 
18 ilm 313
}