OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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
 *
182 ilm 4
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
18 ilm 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.finance.payment.element;
15
 
80 ilm 16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
18 ilm 17
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
18
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
19
import org.openconcerto.erp.core.finance.payment.component.EncaisserMontantSQLComponent;
174 ilm 20
import org.openconcerto.erp.core.sales.invoice.component.SaisieVenteFactureSQLComponent;
21
import org.openconcerto.erp.generationEcritures.GenerationReglementVenteNG;
22
import org.openconcerto.erp.model.PrixTTC;
149 ilm 23
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
18 ilm 24
import org.openconcerto.sql.Configuration;
25
import org.openconcerto.sql.element.SQLComponent;
174 ilm 26
import org.openconcerto.sql.element.SQLElement;
18 ilm 27
import org.openconcerto.sql.element.TreesOfSQLRows;
80 ilm 28
import org.openconcerto.sql.model.FieldPath;
18 ilm 29
import org.openconcerto.sql.model.SQLRow;
80 ilm 30
import org.openconcerto.sql.model.SQLRowAccessor;
18 ilm 31
import org.openconcerto.sql.model.SQLRowListRSH;
32
import org.openconcerto.sql.model.SQLRowValues;
33
import org.openconcerto.sql.model.SQLSelect;
34
import org.openconcerto.sql.model.SQLTable;
35
import org.openconcerto.sql.model.Where;
83 ilm 36
import org.openconcerto.sql.model.graph.Path;
37
import org.openconcerto.sql.model.graph.PathBuilder;
149 ilm 38
import org.openconcerto.sql.preferences.SQLPreferences;
174 ilm 39
import org.openconcerto.sql.view.EditFrame;
80 ilm 40
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
149 ilm 41
import org.openconcerto.sql.view.list.IListe;
42
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
43
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
142 ilm 44
import org.openconcerto.sql.view.list.SQLTableModelSource;
83 ilm 45
import org.openconcerto.utils.CollectionUtils;
149 ilm 46
import org.openconcerto.utils.ExceptionHandler;
174 ilm 47
import org.openconcerto.utils.StringUtils;
18 ilm 48
 
149 ilm 49
import java.awt.event.ActionEvent;
18 ilm 50
import java.sql.SQLException;
51
import java.util.ArrayList;
83 ilm 52
import java.util.Arrays;
53
import java.util.Collection;
18 ilm 54
import java.util.Collections;
132 ilm 55
import java.util.HashSet;
18 ilm 56
import java.util.List;
57
import java.util.Set;
58
 
149 ilm 59
import javax.swing.AbstractAction;
174 ilm 60
import javax.swing.JOptionPane;
61
import javax.swing.SwingUtilities;
149 ilm 62
 
18 ilm 63
public class EncaisserMontantSQLElement extends ComptaSQLConfElement {
64
 
65
    public EncaisserMontantSQLElement() {
66
        super("ENCAISSER_MONTANT", "un encaissement de montant", "encaissements de montant");
149 ilm 67
 
68
        SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
69
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ACOMPTE_DEVIS, false)) {
70
            PredicateRowAction actionClient = new PredicateRowAction(new AbstractAction("Annuler l'acompte") {
71
 
72
                public void actionPerformed(ActionEvent e) {
73
                    final SQLRow selRow = IListe.get(e).getSelectedRow().asRow();
74
                    if (selRow.getBoolean("ACOMPTE")) {
182 ilm 75
                        if (!selRow.isForeignEmpty("ID_DEVIS")) {
76
                            int idDevis = selRow.getForeignID("ID_DEVIS");
77
                            try {
78
                                archive(selRow.getID());
79
                                String up = "UPDATE " + getTable().getTable("DEVIS").getSQLName().quote() + " set \"T_ACOMPTE\"=(SELECT COALESCE(SUM(\"MONTANT\"),0) from "
80
                                        + getTable().getSQLName().quote() + " where \"ID_DEVIS\"=" + idDevis + " AND \"ARCHIVE\"=0) where \"ID_DEVIS\"=" + idDevis;
81
                                getTable().getDBSystemRoot().getDataSource().execute(up);
82
                            } catch (SQLException e1) {
83
                                e1.printStackTrace();
84
                                ExceptionHandler.handle("Erreur lors de l'annulation de l'acompte!", e1);
85
                            }
86
                        } else if (!selRow.isForeignEmpty("ID_COMMANDE_CLIENT")) {
87
                            int idDevis = selRow.getForeignID("ID_COMMANDE_CLIENT");
88
                            try {
89
                                archive(selRow.getID());
90
                                String up = "UPDATE " + getTable().getTable("COMMANDE_CLIENT").getSQLName().quote() + " set \"T_ACOMPTE\"=(SELECT COALESCE(SUM(\"MONTANT\"),0) from "
91
                                        + getTable().getSQLName().quote() + " where \"ID_COMMANDE_CLIENT\"=" + idDevis + " AND \"ARCHIVE\"=0) where \"ID\"=" + idDevis;
92
                                getTable().getDBSystemRoot().getDataSource().execute(up);
93
                            } catch (SQLException e1) {
94
                                e1.printStackTrace();
95
                                ExceptionHandler.handle("Erreur lors de l'annulation de l'acompte!", e1);
96
                            }
149 ilm 97
                        }
98
                    }
99
                }
100
            }, false);
101
            actionClient.setPredicate(IListeEvent.getSingleSelectionPredicate());
102
            getRowActions().add(actionClient);
103
        }
104
 
18 ilm 105
    }
106
 
107
    @Override
108
    protected List<String> getListFields() {
109
        final List<String> l = new ArrayList<String>();
83 ilm 110
            l.add("DATE");
111
            l.add("NOM");
112
            l.add("ID_CLIENT");
113
            // l.add("ID_MOUVEMENT");
114
            l.add("ID_MODE_REGLEMENT");
115
            l.add("MONTANT");
149 ilm 116
            SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
117
            if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ACOMPTE_DEVIS, false)) {
118
                l.add("ACOMPTE");
119
            }
18 ilm 120
        return l;
121
    }
122
 
123
    @Override
124
    protected List<String> getComboFields() {
125
        final List<String> l = new ArrayList<String>();
126
        l.add("DATE");
127
        l.add("MONTANT");
128
        return l;
129
    }
130
 
131
    @Override
132
    public Set<String> getReadOnlyFields() {
133
 
182 ilm 134
        Set<String> s = new HashSet<>();
135
        s.add("ACOMPTE");
136
        s.add("ID_CLIENT");
137
        return s;
18 ilm 138
    }
139
 
180 ilm 140
    @Override
141
    protected synchronized void _initTableSource(final SQLTableModelSource table) {
142
        super._initTableSource(table);
80 ilm 143
 
180 ilm 144
        final BaseSQLTableModelColumn racCol = new BaseSQLTableModelColumn("Report échéance", Boolean.class) {
145
            @Override
146
            protected Object show_(SQLRowAccessor r) {
147
 
148
                return !r.getForeign("ID_MODE_REGLEMENT").getBoolean("COMPTANT");
149
            }
150
 
151
            @Override
152
            public Set<FieldPath> getPaths() {
153
                Path p = new Path(getTable());
154
                Path p2 = p.add(p.getLast().getField("ID_MODE_REGLEMENT"));
155
                return CollectionUtils.createSet(new FieldPath(p2, "COMPTANT"));
156
            }
157
        };
158
 
159
        table.getColumns().add(racCol);
160
 
161
    }
162
 
18 ilm 163
    /*
164
     * (non-Javadoc)
165
     *
166
     * @see org.openconcerto.devis.SQLElement#getComponent()
167
     */
168
    @Override
169
    public SQLComponent createComponent() {
170
        return new EncaisserMontantSQLComponent(this);
171
    }
172
 
173
    @Override
174
    protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {
175
 
176
        // On rétablit les échéances
177
        for (SQLRow row : trees.getRows()) {
182 ilm 178
            for (SQLRow rowEncaisseItems : row.getReferentRows(row.getTable().getTable("ENCAISSER_MONTANT_ELEMENT").getField("ID_ENCAISSER_MONTANT"))) {
18 ilm 179
 
182 ilm 180
                SQLRow rowEch = rowEncaisseItems.getForeignRow("ID_ECHEANCE_CLIENT");
18 ilm 181
                // SI une echeance est associée (paiement non comptant)
182
                if (rowEch.getID() > 1) {
183
                    SQLRowValues rowVals = rowEch.createEmptyUpdateRow();
184
                    rowVals.put("REGLE", Boolean.FALSE);
185
                    if (rowEch.getBoolean("REGLE")) {
182 ilm 186
                        rowVals.put("MONTANT", rowEncaisseItems.getLong("MONTANT_REGLE"));
18 ilm 187
                    } else {
182 ilm 188
                        rowVals.put("MONTANT", rowEch.getLong("MONTANT") + rowEncaisseItems.getLong("MONTANT_REGLE"));
18 ilm 189
                    }
190
                    rowVals.update();
191
                }
182 ilm 192
                Configuration.getInstance().getDirectory().getElement(rowEncaisseItems.getTable()).archive(rowEncaisseItems);
18 ilm 193
            }
182 ilm 194
            if (row.getBoolean("ACOMPTE")) {
195
                if (!row.isForeignEmpty("ID_DEVIS")) {
196
                    int idDevis = row.getForeignID("ID_DEVIS");
197
                    try {
198
                        archive(row.getID());
199
                        String up = "UPDATE " + getTable().getTable("DEVIS").getSQLName().quote() + " set \"T_ACOMPTE\"=(SELECT COALESCE(SUM(\"MONTANT\"),0) from " + getTable().getSQLName().quote()
200
                                + " where \"ID_DEVIS\"=" + idDevis + " AND \"ARCHIVE\"=0) where \"ID_DEVIS\"=" + idDevis;
201
                        getTable().getDBSystemRoot().getDataSource().execute(up);
202
                    } catch (SQLException e1) {
203
                        e1.printStackTrace();
204
                        ExceptionHandler.handle("Erreur lors de l'annulation de l'acompte!", e1);
205
                    }
206
                } else if (!row.isForeignEmpty("ID_COMMANDE_CLIENT")) {
207
                    int idDevis = row.getForeignID("ID_COMMANDE_CLIENT");
208
                    try {
209
                        archive(row.getID());
210
                        String up = "UPDATE " + getTable().getTable("COMMANDE_CLIENT").getSQLName().quote() + " set \"T_ACOMPTE\"=(SELECT COALESCE(SUM(\"MONTANT\"),0) from "
211
                                + getTable().getSQLName().quote() + " where \"ID_COMMANDE_CLIENT\"=" + idDevis + " AND \"ARCHIVE\"=0) where \"ID\"=" + idDevis;
212
                        getTable().getDBSystemRoot().getDataSource().execute(up);
213
                    } catch (SQLException e1) {
214
                        e1.printStackTrace();
215
                        ExceptionHandler.handle("Erreur lors de l'annulation de l'acompte!", e1);
216
                    }
217
                }
218
            }
18 ilm 219
 
220
            // On supprime les mouvements
221
            SQLSelect sel = new SQLSelect(getTable().getBase());
222
 
223
            SQLTable tableMvt = getTable().getTable("MOUVEMENT");
224
            EcritureSQLElement eltEcr = (EcritureSQLElement) Configuration.getInstance().getDirectory().getElement(tableMvt.getTable("ECRITURE"));
225
            sel.addSelectStar(tableMvt);
226
            Where w = new Where(tableMvt.getField("SOURCE"), "=", getTable().getName());
227
            w = w.and(new Where(tableMvt.getField("IDSOURCE"), "=", row.getID()));
228
            sel.setWhere(w);
229
            List<SQLRow> list = (List<SQLRow>) getTable().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel, tableMvt));
230
            for (SQLRow sqlRow : list) {
231
                eltEcr.archiveMouvementProfondeur(sqlRow.getID(), true);
232
            }
233
        }
234
 
235
        super.archive(trees, cutLinks);
236
    }
156 ilm 237
 
180 ilm 238
    public void regleFacture(SQLRow rowAfter, SQLRowValues rowBefore, boolean update) throws Exception {
174 ilm 239
 
180 ilm 240
        if (update && rowBefore == null) {
241
            throw new IllegalArgumentException();
242
        } else if (update) {
243
 
244
            // Recalcul des échéances
245
            for (SQLRowAccessor rowEncaisse : rowBefore.getReferentRows(getTable().getTable("ENCAISSER_MONTANT_ELEMENT"))) {
246
 
247
                SQLRowAccessor rowEch = rowEncaisse.getForeign("ID_ECHEANCE_CLIENT");
248
                // SI une echeance est associée (paiement non comptant)
249
                if (rowEch.getID() > 1) {
250
                    SQLRowValues rowVals = rowEch.createEmptyUpdateRow();
251
                    rowVals.put("REGLE", Boolean.FALSE);
252
                    if (rowEch.getBoolean("REGLE")) {
253
                        rowVals.put("MONTANT", rowEncaisse.getLong("MONTANT_REGLE"));
254
                    } else {
255
                        rowVals.put("MONTANT", rowEch.getLong("MONTANT") + rowEncaisse.getLong("MONTANT_REGLE"));
256
                    }
257
                    rowVals.update();
258
                }
259
                // TODO si pas une echeance, echeance à creer
260
            }
261
 
262
            // On supprime les mouvements
263
            SQLSelect sel = new SQLSelect(getTable().getBase());
264
 
265
            SQLTable tableMvt = getTable().getTable("MOUVEMENT");
266
            EcritureSQLElement eltEcr = (EcritureSQLElement) Configuration.getInstance().getDirectory().getElement(tableMvt.getTable("ECRITURE"));
267
            sel.addSelectStar(tableMvt);
268
            Where w = new Where(tableMvt.getField("SOURCE"), "=", getTable().getName());
269
            w = w.and(new Where(tableMvt.getField("IDSOURCE"), "=", rowBefore.getID()));
270
            sel.setWhere(w);
271
            List<SQLRow> list = (List<SQLRow>) getTable().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel, tableMvt));
272
            for (SQLRow sqlRow : list) {
273
                eltEcr.archiveMouvementProfondeur(sqlRow.getID(), false);
274
            }
275
 
276
            // On supprime si une prochaine échéance a été créé (ex: prélévement)
277
            final SQLRowAccessor nonEmptyForeignMvt = rowBefore.getNonEmptyForeign("ID_MOUVEMENT");
278
            if (nonEmptyForeignMvt != null && nonEmptyForeignMvt.getString("SOURCE").equals("ECHEANCE_CLIENT")) {
279
                eltEcr.archiveMouvementProfondeur(nonEmptyForeignMvt.getID(), true);
280
            }
281
        }
282
 
174 ilm 283
        System.out.println("Génération des ecritures du reglement");
180 ilm 284
        String s = rowAfter.getString("NOM");
285
        SQLRow rowModeRegl = rowAfter.getForeignRow("ID_MODE_REGLEMENT");
174 ilm 286
        SQLRow rowTypeRegl = rowModeRegl.getForeignRow("ID_TYPE_REGLEMENT");
287
 
288
        // Compte Client
180 ilm 289
        SQLRow clientRow = rowAfter.getForeignRow("ID_CLIENT");
174 ilm 290
 
291
        String label = "Règlement vente " + ((s == null) ? "" : s) + " (" + rowTypeRegl.getString("NOM") + ") " + StringUtils.limitLength(clientRow.getString("NOM"), 20);
180 ilm 292
        long montant = rowAfter.getLong("MONTANT");
174 ilm 293
        PrixTTC ttc = new PrixTTC(montant);
294
 
180 ilm 295
        List<SQLRow> l = rowAfter.getReferentRows(rowAfter.getTable().getTable("ENCAISSER_MONTANT_ELEMENT"));
174 ilm 296
        if (l.isEmpty()) {
297
            SwingUtilities.invokeLater(new Runnable() {
298
 
299
                @Override
300
                public void run() {
301
                    JOptionPane.showMessageDialog(null, "Un problème a été rencontré lors de l'encaissement! \n Les écritures comptables non pu être générer!");
302
                }
303
            });
180 ilm 304
            System.err.println("Liste des échéances vides pour l'encaissement ID " + rowAfter.getID());
174 ilm 305
            Thread.dumpStack();
306
            return;
307
        }
180 ilm 308
        new GenerationReglementVenteNG(label, clientRow, ttc, rowAfter.getDate("DATE").getTime(), rowModeRegl, rowAfter, l.get(0).getForeignRow("ID_MOUVEMENT_ECHEANCE"), false, false,
309
                rowAfter.getString("TIERS"), rowAfter.getForeign("ID_COMPTE_PCE_TIERS"));
174 ilm 310
 
311
        // Mise a jour du montant de l'echeance
312
        boolean supplement = false;
313
 
180 ilm 314
        if (!rowAfter.getBoolean("ACOMPTE")) {
174 ilm 315
            // On marque les echeances comme reglees
316
            for (SQLRow sqlRow : l) {
317
 
318
                final SQLRow rowEch = sqlRow.getForeignRow("ID_ECHEANCE_CLIENT");
319
                SQLRowValues rowValsEch = rowEch.createEmptyUpdateRow();
320
                if (sqlRow.getLong("MONTANT_REGLE") >= sqlRow.getLong("MONTANT_A_REGLER")) {
321
                    rowValsEch.put("REGLE", Boolean.TRUE);
322
                    if (sqlRow.getLong("MONTANT_REGLE") > sqlRow.getLong("MONTANT_A_REGLER")) {
323
                        supplement = true;
324
                    }
325
                }
326
                rowValsEch.put("MONTANT", Long.valueOf(rowEch.getLong("MONTANT") - sqlRow.getLong("MONTANT_REGLE")));
327
 
328
                rowValsEch.update();
329
                // this.comboEcheance.rowDeleted(tableEch, rowEch.getID());
330
                // getTable().fireTableModified(rowEch.getID());
331
            }
332
        }
333
        // si le montant réglé est supérieur, on crée une facture de complément
334
        if (supplement) {
335
            SQLElement elt = getDirectory().getElement("SAISIE_VENTE_FACTURE");
336
            SwingUtilities.invokeLater(new Runnable() {
337
 
338
                @Override
339
                public void run() {
340
 
341
                    EditFrame f = new EditFrame(elt, EditFrame.CREATION);
342
                    SaisieVenteFactureSQLComponent comp = (SaisieVenteFactureSQLComponent) f.getSQLComponent();
343
                    comp.setComplement(true);
344
                    f.setVisible(true);
345
                }
346
            });
347
        }
348
 
349
    }
350
 
156 ilm 351
    @Override
352
    protected String createCodeSuffix() {
353
        return ".category";
354
    }
18 ilm 355
}