OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

Rev Author Line No. Line
18 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.erp.core.supplychain.stock.element;
15
 
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
17
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
19 ilm 18
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
174 ilm 19
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
19 ilm 20
import org.openconcerto.erp.core.supplychain.order.component.CommandeSQLComponent;
156 ilm 21
import org.openconcerto.erp.core.supplychain.order.ui.CommandeItemTable;
41 ilm 22
import org.openconcerto.erp.core.supplychain.supplier.component.MouvementStockSQLComponent;
142 ilm 23
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
174 ilm 24
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
18 ilm 25
import org.openconcerto.sql.Configuration;
26
import org.openconcerto.sql.element.SQLComponent;
27
import org.openconcerto.sql.element.SQLElement;
73 ilm 28
import org.openconcerto.sql.element.TreesOfSQLRows;
19 ilm 29
import org.openconcerto.sql.model.SQLBackgroundTableCache;
18 ilm 30
import org.openconcerto.sql.model.SQLBase;
19 ilm 31
import org.openconcerto.sql.model.SQLInjector;
18 ilm 32
import org.openconcerto.sql.model.SQLRow;
19 ilm 33
import org.openconcerto.sql.model.SQLRowListRSH;
18 ilm 34
import org.openconcerto.sql.model.SQLRowValues;
19 ilm 35
import org.openconcerto.sql.model.SQLSelect;
18 ilm 36
import org.openconcerto.sql.model.SQLTable;
19 ilm 37
import org.openconcerto.sql.model.Where;
61 ilm 38
import org.openconcerto.sql.preferences.SQLPreferences;
132 ilm 39
import org.openconcerto.sql.request.ListSQLRequest;
19 ilm 40
import org.openconcerto.sql.users.UserManager;
18 ilm 41
import org.openconcerto.sql.view.EditFrame;
42
import org.openconcerto.sql.view.EditPanel;
19 ilm 43
import org.openconcerto.sql.view.EditPanel.EditMode;
44
import org.openconcerto.sql.view.list.RowValuesTableModel;
73 ilm 45
import org.openconcerto.ui.FrameUtil;
83 ilm 46
import org.openconcerto.utils.ListMap;
18 ilm 47
 
73 ilm 48
import java.math.BigDecimal;
18 ilm 49
import java.sql.SQLException;
50
import java.util.ArrayList;
83 ilm 51
import java.util.Collection;
18 ilm 52
import java.util.List;
83 ilm 53
import java.util.Map.Entry;
18 ilm 54
 
174 ilm 55
import javax.swing.JOptionPane;
19 ilm 56
import javax.swing.SwingUtilities;
18 ilm 57
 
58
public class MouvementStockSQLElement extends ComptaSQLConfElement {
59
 
60
    public MouvementStockSQLElement() {
61
        super("MOUVEMENT_STOCK", "un mouvement de stock", "mouvements de stock");
62
    }
63
 
156 ilm 64
    @Override
65
    public ListMap<String, String> getShowAs() {
66
        ListMap<String, String> map = new ListMap<String, String>();
67
        map.putCollection("ID_STOCK", "ID_DEPOT_STOCK");
68
        return map;
69
    }
70
 
18 ilm 71
    protected List<String> getListFields() {
72
        final List<String> l = new ArrayList<String>();
156 ilm 73
        l.add("ID_STOCK");
18 ilm 74
        l.add("DATE");
75
        l.add("NOM");
76
        l.add("ID_ARTICLE");
77
        l.add("QTE");
83 ilm 78
        l.add("REEL");
18 ilm 79
        return l;
80
    }
81
 
82
    protected List<String> getComboFields() {
83
        final List<String> l = new ArrayList<String>();
84
        l.add("NOM");
85
        l.add("QTE");
86
        return l;
87
    }
88
 
89
    /*
90
     * (non-Javadoc)
91
     *
92
     * @see org.openconcerto.devis.SQLElement#getComponent()
93
     */
94
    public SQLComponent createComponent() {
41 ilm 95
        return new MouvementStockSQLComponent(this);
18 ilm 96
    }
97
 
98
    @Override
73 ilm 99
    protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {
100
        super.archive(trees, cutLinks);
83 ilm 101
        updateStock(trees.getRows(), true);
102
 
73 ilm 103
    }
104
 
61 ilm 105
    /**
18 ilm 106
     * Mise à jour des stocks ajoute la quantité si archive est à false
107
     *
108
     * @param id mouvement stock
109
     * @param archive
156 ilm 110
     * @throws SQLException
18 ilm 111
     */
156 ilm 112
    public ListMap<SQLRow, SQLRowValues> updateStock(Collection<SQLRow> rowsMvt, boolean archive) throws SQLException {
73 ilm 113
        // FIXME: if (SwingUtilities.isEventDispatchThread()) {
114
        // throw new IllegalStateException("This method must be called outside of EDT");
115
        // }
83 ilm 116
        // Stock Reel : inc/dec QTE_REEL, inc/dec QTE_LIV_ATTENTE/inc/dec
117
        // QTE_RECEPT_ATTENTE
118
        // Stock Th : inc/dec QTE_TH, inc/dec QTE_LIV_ATTENTE/inc/dec
119
        // QTE_RECEPT_ATTENTE
120
 
156 ilm 121
        final ListMap<SQLRow, SQLRowValues> map = new ListMap<>();
122
        final SQLTable tableCommandeElement = Configuration.getInstance().getBase().getTable("COMMANDE_ELEMENT");
123
        final SQLElement elementStock = Configuration.getInstance().getDirectory().getElement("STOCK");
124
 
83 ilm 125
        for (SQLRow rowMvtStock : rowsMvt) {
18 ilm 126
 
132 ilm 127
            boolean retour = rowMvtStock.getString("SOURCE") == null || rowMvtStock.getString("SOURCE").startsWith("AVOIR_CLIENT");
19 ilm 128
            // Mise à jour des stocks
156 ilm 129
 
19 ilm 130
            final SQLRow rowArticle = rowMvtStock.getForeignRow("ID_ARTICLE");
73 ilm 131
 
156 ilm 132
            SQLRow rowStock = rowMvtStock.getForeignRow(("ID_STOCK"));
133
            if (rowStock == null || rowStock.isUndefined()) {
134
                rowStock = rowArticle.getForeign("ID_STOCK");
135
            }
136
 
83 ilm 137
            if (rowMvtStock.getBoolean("REEL")) {
138
                float qte = rowStock.getFloat("QTE_REEL");
139
                float qteMvt = rowMvtStock.getFloat("QTE");
18 ilm 140
 
156 ilm 141
                SQLRowValues rowVals = new SQLRowValues(elementStock.getTable());
18 ilm 142
 
83 ilm 143
                float qteNvlle;
144
                float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
145
                float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
146
                if (archive) {
147
                    qteNvlle = qte - qteMvt;
132 ilm 148
                    if (!retour) {
149
                        // Réception
150
                        if (qteMvt > 0) {
151
                            qteNvlleEnAttenteRecept += qteMvt;
152
                        } else {
153
                            // Livraison
154
                            qteNvlleEnAttenteExp -= qteMvt;
155
                        }
83 ilm 156
                    }
157
                } else {
158
                    qteNvlle = qte + qteMvt;
132 ilm 159
                    if (!retour) {
160
                        // Réception
161
                        if (qteMvt > 0) {
162
                            qteNvlleEnAttenteRecept -= qteMvt;
163
                        } else {
164
                            // Livraison
165
                            qteNvlleEnAttenteExp += qteMvt;
166
                        }
83 ilm 167
                    }
168
                }
169
                rowVals.put("QTE_REEL", qteNvlle);
170
                rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
171
                rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
18 ilm 172
 
83 ilm 173
                try {
156 ilm 174
                    rowVals.update(rowStock.getID());
18 ilm 175
 
156 ilm 176
                    SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
177
                    boolean gestionStockMin = prefs.getBoolean(GestionArticleGlobalPreferencePanel.WARNING_STOCK_MIN, true);
178
 
179
                    if (!archive && gestionStockMin && rowStock.getObject("QTE_MIN") != null && qteNvlle < rowStock.getFloat("QTE_MIN")) {
180
                        // final float qteShow = qteNvlle;
181
                        SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCommandeElement);
182
                        SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticle));
183
                        rowValsElt.put("ID_STYLE", 2);
184
                        final SQLRow unite = rowArticle.getForeign("ID_UNITE_VENTE");
185
                        final float qteElt = rowStock.getFloat("QTE_MIN") - qteNvlle;
186
                        if (unite.isUndefined() || unite.getBoolean("A_LA_PIECE")) {
187
                            rowValsElt.put("QTE", Math.round(qteElt));
188
                            rowValsElt.put("QTE_UNITAIRE", BigDecimal.ONE);
189
                        } else {
190
                            rowValsElt.put("QTE", 1);
191
                            rowValsElt.put("QTE_UNITAIRE", new BigDecimal(qteElt));
83 ilm 192
                        }
156 ilm 193
                        rowValsElt.put("ID_TAXE", rowValsElt.getObject("ID_TAXE"));
194
                        rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * qteElt);
195
                        rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * qteElt);
196
                        rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
197
                        map.add(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
83 ilm 198
                    }
199
                } catch (SQLException e) {
156 ilm 200
                    throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
83 ilm 201
                }
202
            } else {
203
                float qte = rowStock.getFloat("QTE_TH");
204
                float qteMvt = rowMvtStock.getFloat("QTE");
19 ilm 205
 
156 ilm 206
                SQLRowValues rowVals = new SQLRowValues(elementStock.getTable());
18 ilm 207
 
83 ilm 208
                float qteNvlle;
209
                float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
210
                float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
211
 
212
                if (archive) {
213
                    qteNvlle = qte - qteMvt;
132 ilm 214
                    if (!retour) {
215
 
216
                        // CommandeF
217
                        if (qteMvt > 0) {
218
                            qteNvlleEnAttenteRecept -= qteMvt;
219
                        } else {
220
                            // CommanceC
221
                            qteNvlleEnAttenteExp += qteMvt;
222
                        }
83 ilm 223
                    }
73 ilm 224
                } else {
83 ilm 225
                    qteNvlle = qte + qteMvt;
132 ilm 226
                    if (!retour) {
227
 
228
                        // CommandeF
229
                        if (qteMvt > 0) {
230
                            qteNvlleEnAttenteRecept += qteMvt;
231
                        } else {
232
                            // CommanceC
233
                            qteNvlleEnAttenteExp -= qteMvt;
234
                        }
83 ilm 235
                    }
73 ilm 236
                }
83 ilm 237
                rowVals.put("QTE_TH", qteNvlle);
238
                rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
239
                rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
240
                try {
156 ilm 241
                    rowVals.update(rowStock.getID());
83 ilm 242
                } catch (SQLException e) {
156 ilm 243
                    throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
83 ilm 244
                }
19 ilm 245
            }
73 ilm 246
 
18 ilm 247
        }
19 ilm 248
        return map;
18 ilm 249
    }
250
 
83 ilm 251
    public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise) {
174 ilm 252
        createCommandeF(col, rowDevise, "");
67 ilm 253
    }
19 ilm 254
 
174 ilm 255
    public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise, final String ref) {
73 ilm 256
        if (SwingUtilities.isEventDispatchThread()) {
257
            throw new IllegalStateException("This method must be called outside of EDT");
258
        }
83 ilm 259
        if (col.size() > 0) {
19 ilm 260
 
73 ilm 261
            final SQLElement commande = Configuration.getInstance().getDirectory().getElement("COMMANDE");
174 ilm 262
            Boolean useCommandeEnCours = SQLPreferences.getMemCached(commande.getTable().getDBRoot()).getBoolean(GestionCommercialeGlobalPreferencePanel.COMMANDE_FOURNISSEUR_EN_COURS, false);
83 ilm 263
            for (final Entry<SQLRow, List<SQLRowValues>> e : col.entrySet()) {
264
                final SQLRow fournisseur = e.getKey();
73 ilm 265
                // On regarde si il existe une commande en cours existante
266
                final SQLSelect sel = new SQLSelect();
267
                sel.addSelectStar(commande.getTable());
268
                Where w = new Where(commande.getTable().getField("EN_COURS"), "=", Boolean.TRUE);
269
                w = w.and(new Where(commande.getTable().getField("ID_FOURNISSEUR"), "=", fournisseur.getID()));
270
                sel.setWhere(w);
19 ilm 271
 
142 ilm 272
                final List<SQLRow> rowsCmd = !useCommandeEnCours ? null
273
                        : (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
19 ilm 274
 
73 ilm 275
                SwingUtilities.invokeLater(new Runnable() {
276
 
277
                    @Override
278
                    public void run() {
19 ilm 279
                        SQLRow commandeExistante = null;
280
                        if (rowsCmd != null && rowsCmd.size() > 0) {
281
                            commandeExistante = rowsCmd.get(0);
282
                        }
283
                        EditFrame frame;
284
                        CommandeSQLComponent cmp;
285
 
286
                        if (commandeExistante != null) {
287
                            frame = new EditFrame(commande, EditMode.MODIFICATION);
288
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
289
                            cmp.select(commandeExistante);
290
                        } else {
291
                            frame = new EditFrame(commande);
292
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
41 ilm 293
                            final SQLRowValues rowVals = new SQLRowValues(commande.getTable());
294
                            final SQLElement eltComm = Configuration.getInstance().getDirectory().getElement("COMMERCIAL");
19 ilm 295
                            int idUser = UserManager.getInstance().getCurrentUser().getId();
296
                            SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));
297
 
298
                            if (rowsComm != null) {
299
                                rowVals.put("ID_COMMERCIAL", rowsComm.getID());
300
                            }
132 ilm 301
                            if (fournisseur != null && !fournisseur.isUndefined()) {
302
                                rowVals.put("ID_FOURNISSEUR", fournisseur.getID());
303
                            }
19 ilm 304
                            if (rowDevise != null) {
305
                                rowVals.put("ID_DEVISE", rowDevise.getID());
306
                            }
67 ilm 307
                            if (commande.getTable().contains("ID_ADRESSE")) {
308
                                rowVals.put("ID_ADRESSE", null);
309
                            }
310
                            rowVals.put("NOM", ref);
19 ilm 311
                            cmp.select(rowVals);
73 ilm 312
                            cmp.getRowValuesTable().getRowValuesTableModel().clearRows();
19 ilm 313
                        }
314
 
156 ilm 315
                        CommandeItemTable itemTable = cmp.getRowValuesTablePanel();
316
 
73 ilm 317
                        final RowValuesTableModel model = cmp.getRowValuesTable().getRowValuesTableModel();
83 ilm 318
                        for (SQLRowValues rowValsElt : e.getValue()) {
19 ilm 319
                            SQLRowValues rowValsMatch = null;
320
                            int index = 0;
321
 
322
                            for (int i = 0; i < model.getRowCount(); i++) {
41 ilm 323
                                final SQLRowValues rowValsCmdElt = model.getRowValuesAt(i);
19 ilm 324
                                if (ReferenceArticleSQLElement.isReferenceEquals(rowValsCmdElt, rowValsElt)) {
325
                                    rowValsMatch = rowValsCmdElt;
326
                                    index = i;
327
                                    break;
328
                                }
329
                            }
330
                            if (rowValsMatch != null) {
174 ilm 331
 
332
                                int qte = rowValsMatch.getInt("QTE");
333
                                BigDecimal qteUV = rowValsMatch.getBigDecimal("QTE_UNITAIRE");
334
 
335
                                if (rowValsMatch.getObject("ID_UNITE_VENTE") != null && rowValsMatch.getForeignID("ID_UNITE_VENTE") != UniteVenteArticleSQLElement.A_LA_PIECE) {
336
                                    qteUV = qteUV.multiply(new BigDecimal(qte));
337
                                    int qteElt = rowValsElt.getInt("QTE");
338
                                    BigDecimal qteUVElt = rowValsElt.getBigDecimal("QTE_UNITAIRE");
339
                                    qteUV = qteUV.add(qteUVElt.multiply(new BigDecimal(qteElt)));
340
                                    qte = 1;
341
                                } else {
342
                                    qte += rowValsElt.getInt("QTE");
343
                                }
344
 
345
                                model.putValue(qte, index, "QTE");
346
                                model.putValue(qteUV, index, "QTE_UNITAIRE");
19 ilm 347
                            } else {
348
                                model.addRow(rowValsElt);
156 ilm 349
                                if (rowValsElt.getObject("ID_ARTICLE") != null && !rowValsElt.isForeignEmpty("ID_ARTICLE")) {
350
                                    Object o = itemTable.tarifCompletion(rowValsElt.getForeign("ID_ARTICLE").asRow(), "PRIX_METRIQUE_HA_1");
351
                                    if (o != null) {
352
                                        model.putValue(o, model.getRowCount() - 1, "PRIX_METRIQUE_HA_1");
353
                                    }
354
                                }
19 ilm 355
                            }
356
                        }
357
 
358
                        frame.pack();
73 ilm 359
                        FrameUtil.show(frame);
360
 
19 ilm 361
                    }
73 ilm 362
                });
363
            }
174 ilm 364
        } else {
365
            SwingUtilities.invokeLater(new Runnable() {
73 ilm 366
 
174 ilm 367
                @Override
368
                public void run() {
369
                    JOptionPane.showMessageDialog(null, "Aucune commande à passer", "Commande fournisseur", JOptionPane.INFORMATION_MESSAGE);
370
                }
371
 
372
            });
19 ilm 373
        }
374
 
375
    }
376
 
132 ilm 377
    @Override
378
    protected void _initListRequest(ListSQLRequest req) {
379
        super._initListRequest(req);
380
        req.addToGraphToFetch("SOURCE", "IDSOURCE");
381
    }
382
 
73 ilm 383
    public static final void showSource(final int id) {
384
        if (!SwingUtilities.isEventDispatchThread()) {
385
            throw new IllegalStateException("This method must be called from EDT");
386
        }
18 ilm 387
        if (id != 1) {
73 ilm 388
            final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
389
            final SQLTable tableMvt = base.getTable("MOUVEMENT_STOCK");
390
            final String stringTableSource = tableMvt.getRow(id).getString("SOURCE");
391
            SwingUtilities.invokeLater(new Runnable() {
392
                public void run() {
393
 
394
                    final EditFrame f;
395
                    // Si une source est associée on l'affiche en readonly
396
                    if (stringTableSource.trim().length() != 0 && tableMvt.getRow(id).getInt("IDSOURCE") != 1) {
397
                        f = new EditFrame(Configuration.getInstance().getDirectory().getElement(stringTableSource), EditPanel.READONLY);
398
                        f.selectionId(tableMvt.getRow(id).getInt("IDSOURCE"));
399
                    } else {
400
                        // Sinon on affiche le mouvement de stock
401
                        f = new EditFrame(Configuration.getInstance().getDirectory().getElement(tableMvt), EditPanel.READONLY);
402
                        f.selectionId(id);
403
                    }
404
                    f.pack();
405
                    FrameUtil.show(f);
406
 
407
                }
408
            });
18 ilm 409
        } else {
410
            System.err.println("Aucun mouvement associé, impossible de modifier ou d'accéder à la source de cette ecriture!");
411
        }
412
    }
57 ilm 413
 
414
    @Override
415
    protected String createCode() {
156 ilm 416
        return createCodeOfPackage() + ".transaction";
57 ilm 417
    }
18 ilm 418
}