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.sales.order.element;
15
 
94 ilm 16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
17
import org.openconcerto.erp.core.common.component.TransfertBaseSQLComponent;
18
import org.openconcerto.erp.core.common.component.TransfertGroupSQLComponent;
18 ilm 19
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
94 ilm 20
import org.openconcerto.erp.core.sales.account.VenteFactureSituationSQLComponent;
21
import org.openconcerto.erp.core.sales.account.VenteFactureSoldeSQLComponent;
18 ilm 22
import org.openconcerto.erp.core.sales.order.component.CommandeClientSQLComponent;
94 ilm 23
import org.openconcerto.erp.core.sales.order.report.CommandeClientXmlSheet;
93 ilm 24
import org.openconcerto.erp.core.sales.order.ui.EtatCommandeClient;
182 ilm 25
import org.openconcerto.erp.core.sales.order.ui.ReliquatCommandeTableModel;
174 ilm 26
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
27
import org.openconcerto.erp.core.sales.product.model.ProductComponent;
28
import org.openconcerto.erp.core.sales.product.model.ProductHelper;
142 ilm 29
import org.openconcerto.erp.core.sales.shipment.component.BonDeLivraisonSQLComponent;
19 ilm 30
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
156 ilm 31
import org.openconcerto.erp.core.supplychain.stock.element.StockSQLElement;
94 ilm 32
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
93 ilm 33
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
18 ilm 34
import org.openconcerto.sql.Configuration;
35
import org.openconcerto.sql.element.SQLComponent;
36
import org.openconcerto.sql.element.SQLElement;
142 ilm 37
import org.openconcerto.sql.element.SQLElementLink.LinkType;
132 ilm 38
import org.openconcerto.sql.element.SQLElementLinksSetup;
90 ilm 39
import org.openconcerto.sql.element.TreesOfSQLRows;
93 ilm 40
import org.openconcerto.sql.model.ConnectionHandlerNoSetup;
41
import org.openconcerto.sql.model.SQLDataSource;
19 ilm 42
import org.openconcerto.sql.model.SQLInjector;
43
import org.openconcerto.sql.model.SQLRow;
94 ilm 44
import org.openconcerto.sql.model.SQLRowAccessor;
93 ilm 45
import org.openconcerto.sql.model.SQLRowListRSH;
19 ilm 46
import org.openconcerto.sql.model.SQLRowValues;
93 ilm 47
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
83 ilm 48
import org.openconcerto.sql.model.SQLSelect;
142 ilm 49
import org.openconcerto.sql.model.SQLSelectJoin;
19 ilm 50
import org.openconcerto.sql.model.SQLTable;
182 ilm 51
import org.openconcerto.sql.model.SQLTableEvent;
52
import org.openconcerto.sql.model.SQLTableEvent.Mode;
53
import org.openconcerto.sql.model.SQLTableModifiedListener;
83 ilm 54
import org.openconcerto.sql.model.Where;
93 ilm 55
import org.openconcerto.sql.preferences.SQLPreferences;
56
import org.openconcerto.sql.request.UpdateBuilder;
57
import org.openconcerto.sql.utils.SQLUtils;
144 ilm 58
import org.openconcerto.sql.view.EditFrame;
180 ilm 59
import org.openconcerto.sql.view.EditPanel;
182 ilm 60
import org.openconcerto.sql.view.EditPanel.EditMode;
61
import org.openconcerto.sql.view.EditPanelListener;
93 ilm 62
import org.openconcerto.sql.view.list.IListe;
63
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
94 ilm 64
import org.openconcerto.sql.view.list.RowAction;
93 ilm 65
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
66
import org.openconcerto.sql.view.list.SQLTableModelColumn;
142 ilm 67
import org.openconcerto.sql.view.list.SQLTableModelSource;
182 ilm 68
import org.openconcerto.ui.PanelFrame;
69
import org.openconcerto.utils.CollectionUtils;
93 ilm 70
import org.openconcerto.utils.CompareUtils;
90 ilm 71
import org.openconcerto.utils.DecimalUtils;
93 ilm 72
import org.openconcerto.utils.ExceptionHandler;
83 ilm 73
import org.openconcerto.utils.ListMap;
94 ilm 74
import org.openconcerto.utils.NumberUtils;
93 ilm 75
import org.openconcerto.utils.cc.ITransformer;
18 ilm 76
 
142 ilm 77
import java.awt.Component;
182 ilm 78
import java.awt.GridBagConstraints;
79
import java.awt.GridBagLayout;
142 ilm 80
import java.awt.event.ActionEvent;
81
import java.io.IOException;
82
import java.math.BigDecimal;
83
import java.math.RoundingMode;
84
import java.sql.SQLException;
85
import java.util.ArrayList;
86
import java.util.Arrays;
87
import java.util.Collection;
88
import java.util.HashSet;
89
import java.util.List;
90
import java.util.Map;
91
import java.util.Set;
92
 
93
import javax.swing.AbstractAction;
94
import javax.swing.JLabel;
182 ilm 95
import javax.swing.JOptionPane;
96
import javax.swing.JPanel;
97
import javax.swing.JScrollPane;
142 ilm 98
import javax.swing.JTable;
99
import javax.swing.SwingUtilities;
100
import javax.swing.table.DefaultTableCellRenderer;
101
 
102
import org.apache.commons.dbutils.ResultSetHandler;
103
import org.apache.commons.dbutils.handlers.ArrayListHandler;
104
 
18 ilm 105
public class CommandeClientSQLElement extends ComptaSQLConfElement {
106
 
107
    public CommandeClientSQLElement() {
108
        super("COMMANDE_CLIENT", "une commande client", "commandes clients");
93 ilm 109
 
110
        SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
111
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ORDER_PACKAGING_MANAGEMENT, true)) {
112
 
113
            for (final EtatCommandeClient etat : EtatCommandeClient.values()) {
114
 
115
                PredicateRowAction action = new PredicateRowAction(new AbstractAction(etat.getTranslation()) {
116
 
117
                    @Override
118
                    public void actionPerformed(ActionEvent e) {
119
                        changeStateOfRows(IListe.get(e).getSelectedRows(), etat);
120
                    }
121
                }, false);
122
                action.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
123
                action.setPath(Arrays.asList("Etat", "Etat", "Etat"));
124
                getRowActions().add(action);
125
            }
126
 
127
            PredicateRowAction actionTransfertBL = new PredicateRowAction(new AbstractAction("Transfert automatique vers BL") {
128
 
129
                @Override
130
                public void actionPerformed(ActionEvent e) {
131
                    TransfertCommandeAutoUtils transfert = new TransfertCommandeAutoUtils(getTable());
182 ilm 132
                    List<SQLRowValues> selectedRows = IListe.get(e).getSelectedRows();
133
                    Set<String> clientBloque = checkClient(selectedRows);
134
                    if (clientBloque.isEmpty()) {
135
                        transfert.transfertMultiBL(IListe.get(e).getSelectedRows());
136
                    } else if (clientBloque.size() == 1) {
137
                        JOptionPane.showMessageDialog(null, "Impossible de faire le transfert car le client " + clientBloque.iterator().next() + " est bloqué!");
138
                    } else {
139
                        JOptionPane.showMessageDialog(null, "Impossible de faire le transfert car les clients " + CollectionUtils.join(clientBloque, ",") + " sont bloqués!");
140
                    }
141
 
93 ilm 142
                }
143
            }, false);
144
            actionTransfertBL.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
145
            getRowActions().add(actionTransfertBL);
146
 
147
            PredicateRowAction actionStock = new PredicateRowAction(new AbstractAction("Vérification des stocks") {
148
 
149
                @Override
150
                public void actionPerformed(ActionEvent e) {
151
                    new Thread("Check Commande To Ship") {
152
                        public void run() {
153
                            try {
154
                                checkCommandeToShip();
155
                            } catch (Exception e) {
156
                                ExceptionHandler.handle("Erreur pendant la vérification du statut des commandes", e);
157
                            }
158
                        }
159
                    }.start();
160
                }
161
 
162
            }, false);
163
            actionStock.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
164
            getRowActions().add(actionStock);
165
 
166
            PredicateRowAction actionFacture = new PredicateRowAction(new AbstractAction("Transfert automatique en facture") {
167
 
168
                @Override
169
                public void actionPerformed(ActionEvent e) {
170
                    TransfertCommandeAutoUtils transfert = new TransfertCommandeAutoUtils(getTable());
182 ilm 171
                    List<SQLRowValues> selectedRows = IListe.get(e).getSelectedRows();
172
                    Set<String> clientBloque = checkClient(selectedRows);
173
                    if (clientBloque.isEmpty()) {
174
                        transfert.transfertFacture(IListe.get(e).getSelectedRows());
175
                    } else if (clientBloque.size() == 1) {
176
                        JOptionPane.showMessageDialog(null, "Impossible de faire le transfert car le client " + clientBloque.iterator().next() + " est bloqué!");
177
                    } else {
178
                        JOptionPane.showMessageDialog(null, "Impossible de faire le transfert car les clients " + CollectionUtils.join(clientBloque, ",") + " sont bloqués!");
179
                    }
180
 
93 ilm 181
                }
182
            }, false);
183
            actionFacture.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
184
            getRowActions().add(actionFacture);
185
 
186
        }
94 ilm 187
 
182 ilm 188
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ACOMPTE_DEVIS, false)) {
189
            PredicateRowAction actionClient = new PredicateRowAction(new AbstractAction("Saisir un acompte") {
190
                EditFrame edit;
191
 
192
                public void actionPerformed(ActionEvent e) {
193
                    final SQLElement eltEncaisser = Configuration.getInstance().getDirectory()
194
                            .getElement(((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ENCAISSER_MONTANT"));
195
 
196
                    if (this.edit == null) {
197
                        this.edit = new EditFrame(eltEncaisser, EditMode.CREATION);
198
                    }
199
                    final SQLRowAccessor selRow = IListe.get(e).getSelectedRow();
200
                    SQLRowValues rowVals = new SQLRowValues(eltEncaisser.getTable());
201
                    rowVals.put("ACOMPTE", true);
202
                    rowVals.put("NOM", "Acompte commande " + selRow.getString("NUMERO"));
203
                    rowVals.put("ID_CLIENT", selRow.getForeignID("ID_CLIENT"));
204
                    rowVals.put("ID_COMMANDE_CLIENT", selRow.getID());
205
                    SQLRowValues rowValsElt = new SQLRowValues(eltEncaisser.getTable().getTable("ENCAISSER_MONTANT_ELEMENT"));
206
                    rowValsElt.put("MONTANT_A_REGLER", selRow.getLong("T_TTC"));
207
                    rowValsElt.put("DATE", selRow.getObject("DATE"));
208
                    rowValsElt.put("ID_ENCAISSER_MONTANT", rowVals);
209
                    this.edit.getSQLComponent().select(rowVals);
210
                    this.edit.setVisible(true);
211
                    this.edit.addEditPanelListener(new EditPanelListener() {
212
 
213
                        @Override
214
                        public void modified() {
215
                        }
216
 
217
                        @Override
218
                        public void inserted(int id) {
219
                            // Put id devis and refresh devis.t_acompte
220
                            SQLRow rowE = eltEncaisser.getTable().getRow(id);
221
                            String up = "UPDATE " + selRow.getTable().getSQLName().quote() + " set \"T_ACOMPTE\"=(SELECT COALESCE(SUM(\"MONTANT\"),0) from " + rowE.getTable().getSQLName().quote()
222
                                    + " where \"ARCHIVE\"=0 and \"ID_COMMANDE_CLIENT\"=" + selRow.getID() + ") where \"ID\"=" + selRow.getID();
223
                            eltEncaisser.getTable().getDBSystemRoot().getDataSource().execute(up);
224
                        }
225
 
226
                        @Override
227
                        public void deleted() {
228
                        }
229
 
230
                        @Override
231
                        public void cancelled() {
232
                        }
233
                    });
234
                }
235
            }, false);
236
            actionClient.setPredicate(IListeEvent.getSingleSelectionPredicate());
237
            getRowActions().add(actionClient);
238
        }
239
 
94 ilm 240
        final List<RowAction> allowedActions = new ArrayList<RowAction>();
241
        // Transfert vers facture
242
        PredicateRowAction bonAction = new PredicateRowAction(new AbstractAction() {
243
            public void actionPerformed(ActionEvent e) {
244
                transfertBonLivraisonClient(IListe.get(e).getSelectedRows());
245
            }
151 ilm 246
        }, true, "sales.order.create.deliverynote");
94 ilm 247
 
248
        // Transfert vers facture
249
        RowAction factureAction = new RowAction(new AbstractAction() {
250
            public void actionPerformed(ActionEvent e) {
251
                transfertFactureClient(IListe.get(e).getSelectedRows());
252
            }
151 ilm 253
        }, true, "sales.order.create.invoice") {
94 ilm 254
 
255
            @Override
256
            public boolean enabledFor(List<SQLRowValues> selection) {
257
                if (selection.isEmpty()) {
258
                    return false;
259
                } else if (selection.size() > 1) {
260
                    return true;
261
                } else {
262
                    BigDecimal d = getAvancement(selection.get(0));
263
                    return d.signum() == 0;
264
                }
265
            }
266
        };
267
 
268
        // Transfert vers facture intermédiaire
269
        RowAction acompteAction = new RowAction(new AbstractAction("Créer une facture intermédiaire") {
270
            public void actionPerformed(ActionEvent e) {
271
                transfertAcompteClient(IListe.get(e).getSelectedRows());
272
            }
273
        }, false, "sales.order.create.account") {
274
            BigDecimal cent = BigDecimal.ONE.movePointRight(2);
275
 
276
            @Override
277
            public boolean enabledFor(List<SQLRowValues> selection) {
278
                if (selection.isEmpty() || selection.size() > 1) {
279
                    return false;
280
                } else {
281
                    BigDecimal d = getAvancement(selection.get(0));
282
                    return NumberUtils.compare(d, cent) != 0;
283
                }
284
            }
285
        };
286
 
287
        // Transfert vers facture solde
288
        RowAction soldeAction = new RowAction(new AbstractAction("Facturer le solde") {
289
            public void actionPerformed(ActionEvent e) {
290
                transfertSoldeClient(IListe.get(e).getSelectedRows());
291
            }
292
        }, false, "sales.order.create.account.solde") {
293
            BigDecimal cent = BigDecimal.ONE.movePointRight(2);
294
 
295
            @Override
296
            public boolean enabledFor(List<SQLRowValues> selection) {
297
                if (selection.isEmpty() || selection.size() > 1) {
298
                    return false;
299
                } else {
300
                    BigDecimal d = getAvancement(selection.get(0));
301
                    return NumberUtils.compare(d, cent) != 0 && NumberUtils.compare(d, BigDecimal.ZERO) != 0;
302
                }
303
            }
304
        };
305
 
306
        // Transfert vers commande
307
        PredicateRowAction cmdAction = new PredicateRowAction(new AbstractAction() {
308
            public void actionPerformed(ActionEvent e) {
309
                final int selectedId = IListe.get(e).getSelectedId();
310
                ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
311
 
312
                    @Override
313
                    public void run() {
314
                        final CommandeClientSQLElement elt = (CommandeClientSQLElement) Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT");
142 ilm 315
                        elt.transfertCommande(selectedId, true);
94 ilm 316
 
317
                    }
318
                });
319
 
320
            }
321
 
322
        }, false, "sales.order.create.supplier.order");
323
 
324
        cmdAction.setPredicate(IListeEvent.getSingleSelectionPredicate());
325
 
326
        bonAction.setPredicate(IListeEvent.getSingleSelectionPredicate());
327
 
182 ilm 328
        // Reliquat
329
        PredicateRowAction reliquatAction = new PredicateRowAction(new AbstractAction() {
330
            public void actionPerformed(ActionEvent e) {
331
                JPanel panelReliquat = new JPanel(new GridBagLayout());
332
                GridBagConstraints c = new GridBagConstraints();
333
                final ReliquatCommandeTableModel dm = new ReliquatCommandeTableModel(IListe.get(e).getSelectedRowAccessor());
334
                if (dm.getRowCount() > 0) {
335
                    JTable table = new JTable(dm);
336
                    JScrollPane comp = new JScrollPane(table);
337
                    c.weightx = 1;
338
                    c.weighty = 1;
339
                    c.fill = GridBagConstraints.BOTH;
340
                    panelReliquat.add(comp, c);
341
                    PanelFrame frame = new PanelFrame(panelReliquat, "Reliquat commande");
342
                    frame.pack();
343
                    frame.setVisible(true);
344
                } else {
345
                    JOptionPane.showMessageDialog(null, "Aucun reliquat restant");
346
                }
347
            }
348
 
349
        }, false, "sales.order.reliquat.show");
350
 
351
        reliquatAction.setPredicate(IListeEvent.getSingleSelectionPredicate());
352
 
353
        MouseSheetXmlListeListener mouseSheetXmlListeListener = new MouseSheetXmlListeListener(this, CommandeClientXmlSheet.class);
94 ilm 354
        mouseSheetXmlListeListener.setGenerateHeader(true);
355
        mouseSheetXmlListeListener.setShowHeader(true);
356
 
180 ilm 357
        // Dupliquer
358
        RowAction cloneAction = getCloneAction();
359
        allowedActions.add(cloneAction);
360
 
94 ilm 361
        allowedActions.add(bonAction);
362
        allowedActions.add(factureAction);
363
        allowedActions.add(acompteAction);
364
        allowedActions.add(soldeAction);
365
        allowedActions.add(cmdAction);
182 ilm 366
        allowedActions.add(reliquatAction);
94 ilm 367
        allowedActions.addAll(mouseSheetXmlListeListener.getRowActions());
368
        getRowActions().addAll(allowedActions);
18 ilm 369
    }
370
 
180 ilm 371
    private boolean chiffrageEditableInUI = true;
372
 
373
    public void setChiffrageEditableInUI(boolean chiffrageEditableInUI) {
374
        this.chiffrageEditableInUI = chiffrageEditableInUI;
375
    }
376
 
377
    public boolean isChiffrageEditableInUI() {
378
        return this.chiffrageEditableInUI;
379
    }
380
 
132 ilm 381
    @Override
382
    protected void setupLinks(SQLElementLinksSetup links) {
383
        super.setupLinks(links);
384
        if (getTable().contains("ID_ADRESSE")) {
385
            links.get("ID_ADRESSE").setType(LinkType.ASSOCIATION);
386
        }
142 ilm 387
        if (getTable().contains("ID_ADRESSE_FACT")) {
388
            links.get("ID_ADRESSE_FACT").setType(LinkType.ASSOCIATION);
389
        }
132 ilm 390
        if (getTable().contains("ID_ADRESSE_LIVRAISON")) {
391
            links.get("ID_ADRESSE_LIVRAISON").setType(LinkType.ASSOCIATION);
392
        }
393
    }
394
 
93 ilm 395
    public SQLRow getNextCommandeToPrepare() {
396
        final SQLTable tableCmd = getTable();
397
        SQLSelect sel = new SQLSelect();
398
        sel.addSelect(tableCmd.getKey());
399
        sel.addSelect(tableCmd.getField("NUMERO"));
400
        sel.addSelect(tableCmd.getField("DATE"));
401
        sel.addSelect(tableCmd.getField("T_HT"));
402
        sel.addSelect(tableCmd.getField("T_TVA"));
403
        sel.addSelect(tableCmd.getField("T_TTC"));
404
        sel.addSelect(tableCmd.getField("PORT_HT"));
405
        sel.addSelect(tableCmd.getField("REMISE_HT"));
406
        sel.addSelect(tableCmd.getField("ID_TAXE_PORT"));
407
        sel.addSelect(tableCmd.getField("ID_CLIENT"));
408
        Where w = new Where(tableCmd.getField("ETAT_COMMANDE"), "=", EtatCommandeClient.A_PREPARER.getId());
409
        sel.setWhere(w);
410
        sel.clearOrder();
411
        sel.addFieldOrder(sel.getAlias(tableCmd.getField("DATE")));
412
        sel.addFieldOrder(sel.getAlias(tableCmd.getField("T_HT")));
413
 
414
        List<SQLRow> result = SQLRowListRSH.execute(sel);
415
        if (result == null || result.size() == 0) {
416
            return null;
417
        } else {
418
            return result.get(0);
419
        }
420
    }
421
 
422
    public int getNbCommandeAPreparer() {
423
        final SQLTable tableCmd = getTable();
424
        SQLSelect sel = new SQLSelect();
425
        sel.addSelect(tableCmd.getKey(), "COUNT");
426
        Where w = new Where(tableCmd.getField("ETAT_COMMANDE"), "=", EtatCommandeClient.A_PREPARER.getId());
427
        sel.setWhere(w);
428
 
429
        Object r = getTable().getDBSystemRoot().getDataSource().executeScalar(sel.asString());
430
        int nb = 0;
431
        if (r != null) {
432
            nb = ((Number) r).intValue();
433
        }
434
        return nb;
435
    }
436
 
437
    public void checkCommandeToShip() throws Exception {
438
        assert !SwingUtilities.isEventDispatchThread();
439
 
440
        SQLUtils.executeAtomic(getTable().getDBSystemRoot().getDataSource(), new ConnectionHandlerNoSetup<Object, IOException>() {
441
            @Override
442
            public Object handle(final SQLDataSource ds) throws SQLException, IOException {
443
                final SQLTable tableCmd = getTable();
444
 
445
                SQLRowValues rowVals = new SQLRowValues(tableCmd);
446
                rowVals.put(tableCmd.getKey().getName(), null);
447
                rowVals.put("NUMERO", null);
448
 
449
                final SQLTable tableCmdElt = tableCmd.getTable("COMMANDE_CLIENT_ELEMENT");
450
                SQLRowValues rowValsElt = new SQLRowValues(tableCmdElt);
451
                rowValsElt.put("QTE", null);
156 ilm 452
                rowValsElt.put("ID_DEPOT_STOCK", null);
93 ilm 453
                rowValsElt.put("QTE_UNITAIRE", null);
454
                rowValsElt.put("ID_COMMANDE_CLIENT", rowVals);
455
 
456
                SQLRowValues rowValsArt = new SQLRowValues(tableCmd.getTable("ARTICLE"));
156 ilm 457
                SQLRowValues rowValsStock = new SQLRowValues(tableCmd.getTable("STOCK"));
458
                rowValsStock.putNulls("QTE_REEL", "QTE_TH");
459
                rowValsStock.put("ID_DEPOT_STOCK", null);
460
                rowValsStock.put("ID_ARTICLE", rowValsArt);
461
                rowValsArt.put("ID_DEPOT_STOCK", null);
93 ilm 462
                rowValsElt.put("ID_ARTICLE", rowValsArt);
463
 
464
                SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowVals);
465
                fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
466
 
467
                    @Override
468
                    public SQLSelect transformChecked(SQLSelect input) {
469
                        Where w = new Where(input.getAlias(tableCmd).getField("ETAT_COMMANDE"), "=", EtatCommandeClient.A_PREPARER.getId());
470
                        w = w.or(new Where(input.getAlias(tableCmd).getField("ETAT_COMMANDE"), "=", EtatCommandeClient.RUPTURE.getId()));
471
                        input.setWhere(w);
472
                        // ORDER BY ETAT COMMANDE et T_HT pour mettre en priorité les ruptures de
473
                        // stock et les commandes les plus chers
474
                        input.clearOrder();
475
                        input.addFieldOrder(input.getAlias(tableCmd.getField("ETAT_COMMANDE")));
476
                        input.addFieldOrder(input.getAlias(tableCmd.getField("T_HT")));
477
                        System.err.println(input.asString());
478
                        return input;
479
                    }
480
                });
481
 
482
                List<SQLRowValues> result = fetcher.fetch();
483
                List<Integer> cmdStockOK = new ArrayList<Integer>();
484
                List<Integer> cmdNoStock = new ArrayList<Integer>();
485
 
486
                // Stock utilisé par les commandes à préparer
487
                StockCommande stockGlobalUsed = new StockCommande();
488
                for (int i = result.size() - 1; i >= 0; i--) {
489
                    SQLRowValues sqlRowValues = result.get(i);
490
                    boolean inStock = true;
491
 
492
                    // Stock utilisé par la commande actuelle
493
                    StockCommande stockCmd = new StockCommande();
494
                    for (SQLRowValues item : sqlRowValues.getReferentRows(tableCmdElt)) {
495
 
156 ilm 496
                        if (item.getObject("ID_ARTICLE") != null && !item.isForeignEmpty("ID_ARTICLE")) {
497
                            final int foreignID = item.getForeignID("ID_ARTICLE");
93 ilm 498
 
156 ilm 499
                            // Stock = stock actuel dans la base - stock utilisé par les commandes
500
                            // déja testées -
501
                            // stock utilisé par la commande en cours (si 2 fois le meme article)
502
                            BigDecimal stock = BigDecimal.ZERO;
503
                            SQLRowAccessor rowStock = StockSQLElement.getStockFetched(item);
504
                            if (rowStock != null) {
505
                                stock = new BigDecimal(rowStock.getFloat("QTE_REEL"));
506
                            }
507
                            stock = stock.subtract(stockCmd.getQty(foreignID)).subtract(stockGlobalUsed.getQty(foreignID));
93 ilm 508
 
156 ilm 509
                            BigDecimal needQty = item.getBigDecimal("QTE_UNITAIRE").multiply(new BigDecimal(item.getInt("QTE")), DecimalUtils.HIGH_PRECISION);
93 ilm 510
 
156 ilm 511
                            stockCmd.addQty(foreignID, needQty);
93 ilm 512
 
156 ilm 513
                            inStock = CompareUtils.compare(stock, needQty) >= 0;
514
 
515
                            if (!inStock) {
516
                                break;
517
                            }
93 ilm 518
                        }
519
                    }
520
 
521
                    if (inStock) {
522
                        Map<Integer, BigDecimal> m = stockCmd.getMap();
523
                        for (Integer id : m.keySet()) {
524
                            stockGlobalUsed.addQty(id, m.get(id));
525
                        }
526
 
527
                        cmdStockOK.add(sqlRowValues.getID());
528
                    } else {
529
                        cmdNoStock.add(sqlRowValues.getID());
530
                    }
531
                }
532
 
533
                List<String> reqs = new ArrayList<String>(2);
534
 
535
                if (cmdStockOK.size() > 0) {
536
                    UpdateBuilder builderStockOK = new UpdateBuilder(tableCmd);
537
                    builderStockOK.setObject("ETAT_COMMANDE", EtatCommandeClient.A_PREPARER.getId());
538
                    builderStockOK.setWhere(new Where(getTable().getKey(), cmdStockOK));
539
                    reqs.add(builderStockOK.asString());
540
                }
541
 
542
                if (cmdNoStock.size() > 0) {
543
                    UpdateBuilder builderNoStock = new UpdateBuilder(tableCmd);
544
                    builderNoStock.setObject("ETAT_COMMANDE", EtatCommandeClient.RUPTURE.getId());
545
                    builderNoStock.setWhere(new Where(getTable().getKey(), cmdNoStock));
546
                    reqs.add(builderNoStock.asString());
547
                }
548
 
549
                if (reqs.size() > 0) {
550
                    List<? extends ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(reqs.size());
551
                    for (String s : reqs) {
552
                        handlers.add(null);
553
                    }
554
                    SQLUtils.executeMultiple(tableCmd.getDBSystemRoot(), reqs, handlers);
555
                    tableCmd.fireTableModified(-1);
556
                }
557
                return null;
558
            }
559
        });
560
 
561
    }
562
 
563
    private void changeStateOfRows(List<SQLRowValues> l, EtatCommandeClient etat) {
564
 
565
        List<Integer> ids = new ArrayList<Integer>(l.size());
566
        for (SQLRowValues sqlRowValues : l) {
567
            ids.add(sqlRowValues.getID());
568
        }
569
 
570
        UpdateBuilder builder = new UpdateBuilder(getTable());
571
        builder.setObject("ETAT_COMMANDE", etat.getId());
572
        builder.setWhere(new Where(getTable().getKey(), ids));
573
 
574
        getTable().getDBSystemRoot().getDataSource().execute(builder.asString());
575
        getTable().fireTableModified(-1);
182 ilm 576
 
577
        if (etat == EtatCommandeClient.ANNULEE) {
578
 
579
            // Suppression des stocks si commande annulée
580
            SQLElement eltMvtStock = getDirectory().getElement("MOUVEMENT_STOCK");
581
            SQLSelect sel = new SQLSelect();
582
            sel.addSelect(eltMvtStock.getTable().getField("ID"));
583
            Where w = new Where(eltMvtStock.getTable().getField("IDSOURCE"), ids);
584
            Where w2 = new Where(eltMvtStock.getTable().getField("SOURCE"), "=", getTable().getName());
585
            sel.setWhere(w.and(w2));
586
 
587
            try {
588
                @SuppressWarnings("rawtypes")
589
                List res = (List) eltMvtStock.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
590
                if (res != null) {
591
                    for (int i = 0; i < res.size(); i++) {
592
                        Object[] tmp = (Object[]) res.get(i);
593
                        eltMvtStock.archive(((Number) tmp[0]).intValue());
594
                    }
595
                }
596
            } catch (SQLException e) {
597
                ExceptionHandler.handle("Erreur lors de la suppression des mouvements de stocks", e);
598
            }
599
        }
93 ilm 600
    }
601
 
18 ilm 602
    /*
603
     * (non-Javadoc)
604
     *
605
     * @see org.openconcerto.devis.BaseSQLElement#getComboFields()
606
     */
607
    protected List<String> getComboFields() {
73 ilm 608
        final List<String> l = new ArrayList<String>();
18 ilm 609
        l.add("NUMERO");
610
        return l;
611
    }
612
 
613
    /*
614
     * (non-Javadoc)
615
     *
616
     * @see org.openconcerto.devis.BaseSQLElement#getListFields()
617
     */
618
    protected List<String> getListFields() {
73 ilm 619
        final List<String> l = new ArrayList<String>();
18 ilm 620
        l.add("NUMERO");
621
        l.add("DATE");
142 ilm 622
        if (getTable().contains("DATE_LIVRAISON_PREV")) {
623
            l.add("DATE_LIVRAISON_PREV");
624
        }
18 ilm 625
        l.add("ID_CLIENT");
41 ilm 626
        l.add("ID_COMMERCIAL");
18 ilm 627
        l.add("T_HT");
628
        l.add("T_TTC");
182 ilm 629
        SQLPreferences prefs = SQLPreferences.getMemCached(getTable().getDBRoot());
630
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ACOMPTE_DEVIS, false)) {
631
            l.add("T_ACOMPTE");
632
        }
156 ilm 633
        if (getTable().getFieldsName().contains("ACOMPTE_COMMANDE")) {
634
            l.add("ACOMPTE_COMMANDE");
635
        }
18 ilm 636
        l.add("NOM");
637
        l.add("INFOS");
93 ilm 638
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ORDER_PACKAGING_MANAGEMENT, true)) {
639
            l.add("NUMERO_EXPEDITION");
640
            l.add("ETAT_COMMANDE");
641
        }
18 ilm 642
        return l;
643
    }
644
 
645
    @Override
28 ilm 646
    public Set<String> getReadOnlyFields() {
73 ilm 647
        final Set<String> s = new HashSet<String>();
28 ilm 648
        s.add("ID_DEVIS");
182 ilm 649
        if (getTable().contains("T_ACOMPTE")) {
650
            s.add("T_ACOMPTE");
651
        }
28 ilm 652
        return s;
653
    }
654
 
67 ilm 655
    @Override
90 ilm 656
    protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {
83 ilm 657
 
90 ilm 658
        for (SQLRow row : trees.getRows()) {
659
 
660
            // Mise à jour des stocks
661
            SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
662
            SQLSelect sel = new SQLSelect();
663
            sel.addSelect(eltMvtStock.getTable().getField("ID"));
664
            Where w = new Where(eltMvtStock.getTable().getField("IDSOURCE"), "=", row.getID());
665
            Where w2 = new Where(eltMvtStock.getTable().getField("SOURCE"), "=", getTable().getName());
666
            sel.setWhere(w.and(w2));
667
 
668
            @SuppressWarnings("rawtypes")
669
            List l = (List) eltMvtStock.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
670
            if (l != null) {
671
                for (int i = 0; i < l.size(); i++) {
672
                    Object[] tmp = (Object[]) l.get(i);
673
                    eltMvtStock.archive(((Number) tmp[0]).intValue());
674
                }
83 ilm 675
            }
676
        }
90 ilm 677
        super.archive(trees, cutLinks);
83 ilm 678
    }
679
 
680
    @Override
142 ilm 681
    protected synchronized void _initTableSource(final SQLTableModelSource source) {
682
        super._initTableSource(source);
73 ilm 683
        // TODO: refaire un renderer pour les commandes transférées en BL
684
        // final CommandeClientRenderer rend = CommandeClientRenderer.getInstance();
685
        // final SQLTableModelColumn col = source.getColumn(getTable().getField("T_HT"));
686
        // col.setColumnInstaller(new IClosure<TableColumn>() {
687
        // @Override
688
        // public void executeChecked(TableColumn input) {
689
        // input.setCellRenderer(rend);
690
        // }
691
        // });
93 ilm 692
        source.init();
693
        SQLPreferences prefs = SQLPreferences.getMemCached(getTable().getDBRoot());
694
        if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ORDER_PACKAGING_MANAGEMENT, true)) {
695
 
696
            SQLTableModelColumn col = source.getColumn(getTable().getField("ETAT_COMMANDE"));
697
            if (col != null) {
698
                col.setRenderer(new DefaultTableCellRenderer() {
699
 
700
                    @Override
701
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
702
 
703
                        JLabel comp = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
704
                        if (value != null) {
705
                            final EtatCommandeClient fromID = EtatCommandeClient.fromID((Integer) value);
706
                            if (fromID != null) {
707
                                comp.setText(fromID.getTranslation());
708
                            } else {
709
                                comp.setText("");
710
                            }
711
                        }
712
                        return comp;
713
                    }
714
                });
715
 
716
            }
717
        }
67 ilm 718
    }
719
 
18 ilm 720
    /*
721
     * (non-Javadoc)
722
     *
723
     * @see org.openconcerto.devis.SQLElement#getComponent()
724
     */
725
    public SQLComponent createComponent() {
726
        return new CommandeClientSQLComponent();
727
    }
728
 
729
    /**
19 ilm 730
     * Transfert d'une commande en commande fournisseur
731
     *
732
     * @param commandeID
733
     */
142 ilm 734
    public void transfertCommande(int commandeID, boolean useCommandeEnCours) {
19 ilm 735
 
736
        SQLElement elt = Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT_ELEMENT");
737
        SQLRow rowCmd = getTable().getRow(commandeID);
738
        List<SQLRow> rows = rowCmd.getReferentRows(elt.getTable());
174 ilm 739
        transfertEltToCommandeF(rows);
740
    }
73 ilm 741
 
174 ilm 742
    public void transfertEltToCommandeF(List<? extends SQLRowAccessor> rowsItems) {
743
        ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
744
 
745
            @Override
746
            public void run() {
747
                ProductHelper helper = new ProductHelper(getTable().getDBRoot());
748
                List<ProductComponent> productComp = new ArrayList<>();
749
                helper.fillProductComponent(rowsItems, productComp, 1, 0, 1);
750
 
751
                List<ProductComponent> leafItems = helper.getChildWithQtyFrom(productComp);
752
 
753
                final ListMap<SQLRow, SQLRowValues> map = new ListMap<SQLRow, SQLRowValues>();
754
                final Set<Integer> stockChecked = new HashSet<Integer>();
755
                for (ProductComponent comp : leafItems) {
756
                    SQLRowAccessor rowArticleFind = comp.getProduct();
757
 
758
                    SQLRow row = rowArticleFind.asRow();
759
                    SQLRowAccessor rowStock = comp.getStock();
760
                    int value = 0;
761
                    if (row.getBoolean("GESTION_STOCK") && !stockChecked.contains(rowStock.getID())) {
762
                        stockChecked.add(rowStock.getID());
763
 
764
                        value = -Math.round(rowStock.getFloat("QTE_TH") - rowStock.getFloat("QTE_MIN"));
765
                    } else if (!row.getBoolean("GESTION_STOCK")) {
766
                        value = comp.getQty().intValue();
767
                    }
768
                    if (value > 0) {
769
 
770
                        SQLInjector inj = SQLInjector.getInjector(row.getTable(), row.getTable().getTable("COMMANDE_ELEMENT"));
771
                        SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(row));
772
 
773
                        int qte = 1;
774
                        BigDecimal qteUV = BigDecimal.ONE;
775
 
776
                        if (row.getObject("ID_UNITE_VENTE") != null && row.getForeignID("ID_UNITE_VENTE") != UniteVenteArticleSQLElement.A_LA_PIECE) {
777
                            qteUV = comp.getQty();
778
                        } else {
779
                            qte = comp.getQty().setScale(0, RoundingMode.HALF_UP).intValue();
780
                        }
781
 
782
                        rowValsElt.put("QTE", qte);
783
                        rowValsElt.put("QTE_UNITAIRE", qteUV);
784
 
785
                        rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
786
                        rowValsElt.put("T_PA_HT", ((BigDecimal) rowValsElt.getObject("PA_HT")).multiply(new BigDecimal(rowValsElt.getInt("QTE")), DecimalUtils.HIGH_PRECISION));
787
                        rowValsElt.put("T_PA_TTC", ((BigDecimal) rowValsElt.getObject("T_PA_HT")).multiply(new BigDecimal((rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0)),
788
                                DecimalUtils.HIGH_PRECISION));
182 ilm 789
                        final SQLRow asRow = rowArticleFind.getForeign("ID_FOURNISSEUR").asRow();
790
                        final SQLRowAccessor rowDeviseF = asRow.getNonEmptyForeign("ID_DEVISE");
791
                        if (rowDeviseF != null) {
792
                            rowValsElt.put("ID_DEVISE", rowDeviseF.getID());
793
                        }
174 ilm 794
                        map.add(rowArticleFind.getForeign("ID_FOURNISSEUR").asRow(), rowValsElt);
795
                    }
796
 
156 ilm 797
                }
174 ilm 798
                MouvementStockSQLElement.createCommandeF(map, null, "");
132 ilm 799
            }
174 ilm 800
        });
19 ilm 801
    }
94 ilm 802
 
803
    /**
804
     * Transfert en BL
805
     *
806
     * @param row
807
     */
142 ilm 808
    public void transfertBonLivraisonClient(final List<SQLRowValues> rows) {
809
        BonDeLivraisonSQLComponent comp = (BonDeLivraisonSQLComponent) TransfertBaseSQLComponent.openTransfertFrame(rows, "BON_DE_LIVRAISON").getSQLComponent();
810
        final SQLTable tableElt = comp.getElement().getTable().getTable("BON_DE_LIVRAISON_ELEMENT");
811
        SQLRowValues rowVals = new SQLRowValues(tableElt);
812
        rowVals.put("QTE_UNITAIRE", null);
813
        rowVals.put("QTE", null);
814
        rowVals.put("QTE_LIVREE", null);
815
        rowVals.put("ID_ARTICLE", null);
156 ilm 816
        rowVals.put("PV_HT", null);
817
        rowVals.put("ID_COMMANDE_CLIENT_ELEMENT", null);
142 ilm 818
 
819
        SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowVals);
820
        fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
821
 
822
            @Override
823
            public SQLSelect transformChecked(SQLSelect input) {
824
                List<Integer> ids = new ArrayList<Integer>(rows.size());
825
                for (SQLRowValues sqlRowValues : rows) {
826
                    ids.add(sqlRowValues.getID());
827
                }
828
                SQLSelectJoin joinBR = input.addJoin("RIGHT", tableElt.getTable("BON_DE_LIVRAISON_ELEMENT").getField("ID_BON_DE_LIVRAISON"));
829
                SQLSelectJoin joinTR = input.addBackwardJoin("RIGHT", tableElt.getTable("TR_COMMANDE_CLIENT").getField("ID_BON_DE_LIVRAISON"), joinBR.getJoinedTable().getAlias());
830
                joinTR.setWhere(new Where(joinTR.getJoinedTable().getField("ID_COMMANDE_CLIENT"), ids));
831
                System.err.println(input.asString());
832
                return input;
833
            }
834
        });
156 ilm 835
        comp.loadQuantity(fetcher.fetch(), "COMMANDE_CLIENT_ELEMENT");
182 ilm 836
        comp.removeZeroQtyLines();
94 ilm 837
    }
838
 
839
    /**
840
     * Transfert en Facture
841
     *
842
     * @param row
843
     */
144 ilm 844
    public EditFrame transfertFactureClient(List<SQLRowValues> rows) {
845
        return TransfertBaseSQLComponent.openTransfertFrame(rows, "SAISIE_VENTE_FACTURE");
94 ilm 846
 
847
    }
848
 
849
    /**
850
     * Transfert en Facture
851
     *
852
     * @param row
853
     */
144 ilm 854
    public EditFrame transfertAcompteClient(List<SQLRowValues> rows) {
855
        return TransfertGroupSQLComponent.openTransfertFrame(rows, "SAISIE_VENTE_FACTURE", VenteFactureSituationSQLComponent.ID);
94 ilm 856
    }
857
 
858
    /**
859
     * Transfert en Facture
860
     *
861
     * @param row
862
     */
144 ilm 863
    public EditFrame transfertSoldeClient(List<SQLRowValues> rows) {
864
        return TransfertGroupSQLComponent.openTransfertFrame(rows, "SAISIE_VENTE_FACTURE", VenteFactureSoldeSQLComponent.ID);
94 ilm 865
    }
866
 
151 ilm 867
    public BigDecimal getAvancement(SQLRowAccessor r) {
94 ilm 868
        Collection<? extends SQLRowAccessor> rows = r.getReferentRows(r.getTable().getTable("TR_COMMANDE_CLIENT"));
869
        long totalFact = 0;
870
        long total = r.getLong("T_HT");
871
        for (SQLRowAccessor row : rows) {
872
            if (!row.isForeignEmpty("ID_SAISIE_VENTE_FACTURE")) {
873
                SQLRowAccessor rowFact = row.getForeign("ID_SAISIE_VENTE_FACTURE");
874
                Long l = rowFact.getLong("T_HT");
875
                totalFact += l;
876
            }
877
        }
878
        if (total > 0) {
879
            return new BigDecimal(totalFact).divide(new BigDecimal(total), DecimalUtils.HIGH_PRECISION).movePointRight(2).setScale(2, RoundingMode.HALF_UP);
880
        } else {
881
            return BigDecimal.ONE.movePointRight(2);
882
        }
883
    }
156 ilm 884
 
180 ilm 885
    public RowAction getCloneAction() {
886
        return new RowAction(new AbstractAction() {
887
 
888
            public void actionPerformed(ActionEvent e) {
889
                SQLRowAccessor selectedRow = IListe.get(e).getSelectedRow();
890
 
891
                EditFrame editFrame = new EditFrame(CommandeClientSQLElement.this, EditPanel.CREATION);
892
 
893
                ((CommandeClientSQLComponent) editFrame.getSQLComponent()).loadCommandeExistant(selectedRow.getID());
894
                editFrame.setVisible(true);
895
            }
896
        }, true, "sales.quote.clone") {
897
            @Override
898
            public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowValues> selection) {
899
                return (selection != null && selection.size() == 1);
900
            }
901
        };
902
    }
903
 
156 ilm 904
    @Override
905
    protected String createCode() {
906
        return "sales.order";
182 ilm 907
 
908
        // r32617 | ludo | 2021-12-20 11:42:44 CET
909
        //
910
        // blocage des intéractions
911
        // ----------------------------------------------------------------------------
156 ilm 912
    }
913
 
182 ilm 914
    private final List<SQLTableModifiedListener> listenerCmdInserted = new ArrayList<>();
915
 
916
    public void addInsertedCmdListener(SQLTableModifiedListener l) {
917
        this.listenerCmdInserted.add(l);
918
    }
919
 
920
    public void removeInsertedCmdListener(SQLTableModifiedListener l) {
921
        this.listenerCmdInserted.remove(l);
922
    }
923
 
924
    public void fireInsertedCmdListener(SQLRow row) {
925
        for (SQLTableModifiedListener sqlTableModifiedListener : this.listenerCmdInserted) {
926
            sqlTableModifiedListener.tableModified(new SQLTableEvent(row, Mode.ROW_ADDED, null));
927
        }
928
    }
929
 
930
    private Set<String> checkClient(List<? extends SQLRowAccessor> rows) {
931
 
932
        Set<String> clientBloque = new HashSet<>();
933
        for (SQLRowAccessor sqlRowAccessor : rows) {
934
            SQLRowAccessor client = sqlRowAccessor.getForeign("ID_CLIENT").fetchNewRow();
935
            if (client.getBoolean("BLOQUE_LIVRAISON") || client.getBoolean("BLOQUE")) {
936
                clientBloque.add(client.getString("CODE") + " " + client.getString("NOM"));
937
            }
938
        }
939
        return clientBloque;
940
    }
941
 
18 ilm 942
}