OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
67 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
 
16
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
17
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
18
import org.openconcerto.sql.Configuration;
19
import org.openconcerto.sql.model.SQLRow;
20
import org.openconcerto.sql.model.SQLRowAccessor;
21
import org.openconcerto.sql.model.SQLRowValues;
22
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
23
import org.openconcerto.sql.model.SQLTable;
24
 
25
import java.math.BigDecimal;
26
import java.math.MathContext;
27
import java.math.RoundingMode;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
 
32
public class TotalCalculator {
33
 
34
    private static String FIELD_SERVICE = "SERVICE";
35
    private static String FIELD_POIDS = "POIDS";
36
    private final String fieldHT, fieldHA, fieldDevise;
37
 
38
    private SQLRowAccessor rowDefaultCptProduit, rowDefaultCptService, rowDefaultCptTVA;
39
    private static final SQLTable tablePrefCompte = Configuration.getInstance().getRoot().findTable("PREFS_COMPTE");
40
    private static final SQLRow rowPrefsCompte = tablePrefCompte.getRow(2);
41
 
42
    double totalPoids;
43
 
44
    private BigDecimal totalDevise, totalDeviseSel;
45
    private BigDecimal totalHA, totalHASel;
46
    private BigDecimal totalService, totalServiceSel;
47
    private BigDecimal totalTTC, totalTTCSel;
48
    private long remiseHT, remiseRestante;
49
 
50
    // Total des HT par comptes
51
    private Map<SQLRowAccessor, BigDecimal> mapHt = new HashMap<SQLRowAccessor, BigDecimal>();
52
    private Map<SQLRowAccessor, BigDecimal> mapHtSel = new HashMap<SQLRowAccessor, BigDecimal>();
53
 
54
    // Total des TVA par comptes
55
    private Map<SQLRowAccessor, BigDecimal> mapHtTVA = new HashMap<SQLRowAccessor, BigDecimal>();
56
    private Map<SQLRowAccessor, BigDecimal> mapHtTVASel = new HashMap<SQLRowAccessor, BigDecimal>();
57
    int[] selectedRows;
58
 
59
    private Boolean bServiceActive;
60
    private BigDecimal totalHTAvantRemise;
61
 
62
    // TODO Gestion des achats
63
    public TotalCalculator(String fieldHA, String fieldHT, String fieldDeviseTotal) {
64
 
65
        initValues();
66
 
67
        this.fieldDevise = fieldDeviseTotal;
68
        this.fieldHA = fieldHA;
69
        this.fieldHT = fieldHT;
70
 
71
        // Comptes par défaut
72
        this.rowDefaultCptService = rowPrefsCompte.getForeign("ID_COMPTE_PCE_VENTE_SERVICE");
73
        if (this.rowDefaultCptService == null || this.rowDefaultCptService.isUndefined()) {
74
            try {
75
                this.rowDefaultCptService = ComptePCESQLElement.getRowComptePceDefault("VentesServices");
76
            } catch (Exception e) {
77
                e.printStackTrace();
78
            }
79
        }
80
 
81
        this.rowDefaultCptProduit = rowPrefsCompte.getForeign("ID_COMPTE_PCE_VENTE_PRODUIT");
82
        if (this.rowDefaultCptProduit == null || this.rowDefaultCptProduit.isUndefined()) {
83
            try {
84
                this.rowDefaultCptProduit = ComptePCESQLElement.getRowComptePceDefault("VentesProduits");
85
            } catch (Exception e) {
86
                e.printStackTrace();
87
            }
88
        }
89
 
90
        this.rowDefaultCptTVA = rowPrefsCompte.getForeign("ID_COMPTE_PCE_TVA_VENTE");
91
        if (this.rowDefaultCptTVA == null || this.rowDefaultCptTVA.isUndefined()) {
92
            try {
93
                this.rowDefaultCptTVA = ComptePCESQLElement.getRowComptePceDefault("TVACollectee");
94
            } catch (Exception e) {
95
                e.printStackTrace();
96
            }
97
        }
98
 
99
    }
100
 
101
    /**
102
     * Définition d'une remise HT à appliquer
103
     *
104
     * @param remiseHT montant de la remise en cents
105
     * @param totalHTAvantRemise montant de la facture avant remise
106
     */
107
    public void setRemise(long remiseHT, BigDecimal totalHTAvantRemise) {
108
        this.remiseHT = remiseHT;
109
        this.remiseRestante = remiseHT;
110
        this.totalHTAvantRemise = totalHTAvantRemise;
111
    }
112
 
113
    /**
114
     * Gestion de la vente de service
115
     *
116
     * @param b
117
     */
118
    public void setServiceActive(boolean b) {
119
        this.bServiceActive = b;
120
    }
121
 
122
    /**
123
     * Remise à zéro des valeurs de calcul
124
     */
125
    public void initValues() {
126
        this.remiseHT = 0;
127
        this.remiseRestante = 0;
128
        this.totalHTAvantRemise = BigDecimal.ZERO;
129
 
130
        this.selectedRows = null;
131
 
132
        this.totalTTC = BigDecimal.ZERO;
133
        this.totalTTCSel = BigDecimal.ZERO;
134
 
135
        this.totalHA = BigDecimal.ZERO;
136
        this.totalHASel = BigDecimal.ZERO;
137
 
138
        this.totalService = BigDecimal.ZERO;
139
        this.totalServiceSel = BigDecimal.ZERO;
140
 
141
        this.totalDeviseSel = BigDecimal.ZERO;
142
        this.totalDevise = BigDecimal.ZERO;
143
 
144
        this.totalPoids = 0;
145
 
146
        // Total des HT par comptes
147
        this.mapHt.clear();
148
        this.mapHtSel.clear();
149
 
150
        // Total des TVA par comptes
151
        this.mapHtTVA.clear();
152
        this.mapHtTVASel.clear();
153
 
154
    }
155
 
156
    public void setSelectedRows(int[] selectedRows) {
157
        this.selectedRows = selectedRows;
158
    }
159
 
160
    public void addEchantillon(BigDecimal ht, SQLRowAccessor tva) {
161
        addHT(ht, tva, this.rowDefaultCptProduit, false);
162
    }
163
 
164
    private Map<Integer, SQLRowAccessor> mapTVA;
165
    final SQLTable tvaTable = Configuration.getInstance().getRoot().findTable("TAXE");
166
    final SQLTable compteTable = Configuration.getInstance().getRoot().findTable("COMPTE_PCE");
167
 
168
    /**
169
     * Mise en cache des comptes de TVA
170
     */
171
    private void fetchTVA() {
172
        mapTVA = new HashMap<Integer, SQLRowAccessor>();
173
        SQLRowValues rowVals = new SQLRowValues(tvaTable);
174
        SQLRowValues rowValsC1 = new SQLRowValues(compteTable);
175
        rowValsC1.put("NUMERO", null);
176
        rowValsC1.put("ID", null);
177
 
178
        rowVals.put(tvaTable.getKey().getName(), null);
179
        rowVals.put("ID_COMPTE_PCE", rowValsC1);
180
 
181
        SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(rowVals);
182
        List<SQLRowValues> rowValsList = fetch.fetch();
183
 
184
        for (SQLRowValues sqlRowValues : rowValsList) {
185
            mapTVA.put(sqlRowValues.getID(), sqlRowValues);
186
        }
187
    }
188
 
189
    private void addHT(BigDecimal ht, SQLRowAccessor tva, SQLRowAccessor cptArticle, boolean selection) {
190
 
191
        BigDecimal ttc;
192
        BigDecimal totalTVA;
193
 
194
        if (tva == null || tva.isUndefined()) {
195
            ttc = ht;
196
            totalTVA = BigDecimal.ZERO;
197
        } else {
198
            BigDecimal tauxTVA = BigDecimal.valueOf(TaxeCache.getCache().getTauxFromId(tva.getID())).movePointLeft(2);
199
            ttc = tauxTVA.add(BigDecimal.ONE).multiply(ht, MathContext.DECIMAL128);
200
            totalTVA = ttc.subtract(ht);
201
        }
202
 
203
        if (tva != null && !tva.isUndefined()) {
204
            SQLRowAccessor rowCptTva = tva.getForeign("ID_COMPTE_PCE");
205
            if (rowCptTva == null || rowCptTva.isUndefined()) {
206
                rowCptTva = this.rowDefaultCptTVA;
207
            }
208
            if (mapHtTVA.get(rowCptTva) == null) {
209
                mapHtTVA.put(rowCptTva, totalTVA);
210
            } else {
211
                BigDecimal l = mapHtTVA.get(rowCptTva);
212
                mapHtTVA.put(rowCptTva, l.add(totalTVA));
213
            }
214
            if (selection) {
215
                if (mapHtTVASel.get(rowCptTva) == null) {
216
                    mapHtTVASel.put(rowCptTva, totalTVA);
217
                } else {
218
                    BigDecimal l = mapHtTVASel.get(rowCptTva);
219
                    mapHtTVASel.put(rowCptTva, l.add(totalTVA));
220
                }
221
            }
222
        }
223
 
224
        if (mapHt.get(cptArticle) == null) {
225
            mapHt.put(cptArticle, ht);
226
        } else {
227
            BigDecimal l = mapHt.get(cptArticle);
228
            mapHt.put(cptArticle, l.add(ht));
229
        }
230
 
231
        this.totalTTC = this.totalTTC.add(ttc);
232
 
233
        if (selection) {
234
 
235
            if (mapHtSel.get(cptArticle) == null) {
236
                mapHtSel.put(cptArticle, ht);
237
            } else {
238
                BigDecimal l = mapHtSel.get(cptArticle);
239
                mapHtSel.put(cptArticle, l.add(ht));
240
            }
241
            this.totalTTCSel = this.totalTTCSel.add(ttc);
242
        }
243
    }
244
 
245
    private static boolean containsInt(int[] tab, int i) {
246
        if (tab == null) {
247
            return false;
248
        }
249
 
250
        for (int j = 0; j < tab.length; j++) {
251
            if (tab[j] == i) {
252
                return true;
253
            }
254
        }
255
        return false;
256
    }
257
 
258
    public void addLine(SQLRowAccessor rowAccessorLine, SQLRowAccessor article, int lineNumber, boolean last) {
259
 
260
        // Total HT de la ligne
261
        BigDecimal totalLineHT = rowAccessorLine.getObject(fieldHT) == null ? BigDecimal.ZERO : (BigDecimal) rowAccessorLine.getObject(fieldHT);
262
 
263
        // Prix Unitaire de la ligne
264
        // TODO voir pour passer le prix total et non le prix unitaire
265
        BigDecimal totalHALigne = rowAccessorLine.getObject(fieldHA) == null ? BigDecimal.ZERO : (BigDecimal) rowAccessorLine.getObject(fieldHA);
266
 
267
        Boolean service = rowAccessorLine.getBoolean(FIELD_SERVICE);
268
 
269
        BigDecimal totalLineDevise = (fieldDevise == null || rowAccessorLine.getObject(fieldDevise) == null) ? BigDecimal.ZERO : (BigDecimal) rowAccessorLine.getObject(fieldDevise);
270
 
271
        Number nPoids = (Number) rowAccessorLine.getObject(FIELD_POIDS);
272
 
273
        // Si il y a une remise à appliquer
274
        if (this.remiseHT != 0 && this.remiseRestante > 0) {
275
 
276
            // Si c'est la derniere ligne, on applique le restant de la remise
277
            if (last) {
278
                totalLineHT = totalLineHT.subtract(new BigDecimal(this.remiseRestante).movePointLeft(2));
279
                this.remiseRestante = 0;
280
            } else {
281
                BigDecimal percent = totalLineHT.divide(this.totalHTAvantRemise, MathContext.DECIMAL128);
282
 
283
                BigDecimal remiseApply = percent.multiply(new BigDecimal(this.remiseHT), MathContext.DECIMAL128).setScale(0, RoundingMode.HALF_UP);
284
                totalLineHT = totalLineHT.subtract(remiseApply.movePointLeft(2));
285
                this.remiseRestante -= remiseApply.longValue();
286
            }
287
        }
288
 
289
        SQLRowAccessor cpt = this.rowDefaultCptProduit;
290
        if (article != null && !article.isUndefined()) {
291
            SQLRowAccessor compteArticle = article.getForeign("ID_COMPTE_PCE");
292
            if (compteArticle != null && !compteArticle.isUndefined()) {
293
                cpt = compteArticle;
294
            } else {
295
                SQLRowAccessor familleArticle = article.getForeign("ID_FAMILLE_ARTICLE");
296
                if (familleArticle != null && !familleArticle.isUndefined()) {
297
                    SQLRowAccessor compteFamilleArticle = familleArticle.getForeign("ID_COMPTE_PCE");
298
                    if (compteFamilleArticle != null && !compteFamilleArticle.isUndefined()) {
299
                        cpt = compteFamilleArticle;
300
                    }
301
                }
302
            }
303
        }
304
 
305
        // Total Service
306
        if (bServiceActive != null && bServiceActive) {
307
            if (service != null && service.booleanValue()) {
308
                totalService = totalService.add(totalLineHT);
309
                cpt = this.rowDefaultCptService;
310
            }
311
        }
312
 
313
        // Total HA
314
        this.totalHA = this.totalHA.add(totalHALigne);
315
 
316
        // Total Devise
317
        if (totalLineDevise != null) {
318
            totalDevise = totalDevise.add(totalLineDevise);
319
        }
320
 
321
        // Total Poids
322
 
323
        totalPoids += nPoids == null ? 0 : nPoids.doubleValue();
324
 
325
        // Calcul total sélectionné
326
        boolean selection = containsInt(selectedRows, lineNumber);
327
        if (selection) {
328
 
329
            totalHASel = totalHASel.add(totalHALigne);
330
 
331
            if (bServiceActive != null && bServiceActive) {
332
                if (service) {
333
                    totalServiceSel = totalServiceSel.add(totalLineHT);
334
                }
335
            }
336
 
337
            if (totalLineDevise != null) {
338
                totalDeviseSel = totalDeviseSel.add(totalLineDevise);
339
            }
340
        }
341
 
342
        if (mapTVA == null) {
343
            fetchTVA();
344
        }
345
        addHT(totalLineHT, mapTVA.get(rowAccessorLine.getObject("ID_TAXE")), cpt, selection);
346
    }
347
 
348
    /**
349
     * Vérifie si ht + tva = ttc
350
     */
351
    public void checkResult() {
352
        BigDecimal ht = getTotalHT();
353
 
354
        BigDecimal tva = getTotalTVA();
355
 
356
        BigDecimal totalTTC2 = getTotalTTC();
357
        BigDecimal reste = totalTTC2.subtract(ht.add(tva));
358
        if (reste.compareTo(BigDecimal.ZERO) != 0) {
359
            System.err.println("HT " + ht);
360
            System.err.println("TVA " + tva);
361
            System.err.println("TTC " + totalTTC2);
362
            Thread.dumpStack();
363
            SQLRow row = ComptePCESQLElement.getRow("758", "Ecarts arrondis");
364
            // TODO Check if row already exist in MAP ??
365
            this.mapHt.put(row, reste);
366
        }
367
    }
368
 
369
    public BigDecimal getTotalDevise() {
370
        return totalDevise;
371
    }
372
 
373
    public BigDecimal getTotalDeviseSel() {
374
        return totalDeviseSel;
375
    }
376
 
377
    public BigDecimal getTotalHA() {
378
        return totalHA;
379
    }
380
 
381
    public BigDecimal getTotalHASel() {
382
        return totalHASel;
383
    }
384
 
385
    public double getTotalPoids() {
386
        return totalPoids;
387
    }
388
 
389
    public BigDecimal getTotalService() {
390
        return totalService;
391
    }
392
 
393
    public BigDecimal getTotalServiceSel() {
394
        return totalServiceSel;
395
    }
396
 
397
    public BigDecimal getTotalHT() {
398
        BigDecimal ht = BigDecimal.ZERO;
399
        for (SQLRowAccessor row : this.mapHt.keySet()) {
400
            ht = ht.add(this.mapHt.get(row).setScale(2, RoundingMode.HALF_UP));
401
        }
402
 
403
        return ht;
404
    }
405
 
406
    public BigDecimal getTotalTVA() {
407
        BigDecimal tva = BigDecimal.ZERO;
408
        for (SQLRowAccessor row : this.mapHtTVA.keySet()) {
409
            tva = tva.add(this.mapHtTVA.get(row).setScale(2, RoundingMode.HALF_UP));
410
        }
411
        return tva;
412
    }
413
 
414
    public BigDecimal getTotalTTC() {
415
 
416
        return this.totalTTC.setScale(2, RoundingMode.HALF_UP);
417
    }
418
 
419
    public BigDecimal getTotalHTSel() {
420
        BigDecimal ht = BigDecimal.ZERO;
421
        for (SQLRowAccessor row : this.mapHtSel.keySet()) {
422
            ht = ht.add(this.mapHtSel.get(row).setScale(2, RoundingMode.HALF_UP));
423
        }
424
 
425
        return ht;
426
    }
427
 
428
    public BigDecimal getTotalTVASel() {
429
        BigDecimal tva = BigDecimal.ZERO;
430
        for (SQLRowAccessor row : this.mapHtTVASel.keySet()) {
431
            tva = tva.add(this.mapHtTVASel.get(row).setScale(2, RoundingMode.HALF_UP));
432
        }
433
        return tva;
434
    }
435
 
436
    public BigDecimal getTotalTTCSel() {
437
 
438
        return this.totalTTCSel.setScale(2, RoundingMode.HALF_UP);
439
    }
440
 
441
    public Map<SQLRowAccessor, BigDecimal> getMapHt() {
442
        return mapHt;
443
    }
444
 
445
    public Map<SQLRowAccessor, BigDecimal> getMapHtTVA() {
446
        return mapHtTVA;
447
    }
448
}