OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 57 | Rev 67 | 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;
19
import org.openconcerto.erp.core.supplychain.order.component.CommandeSQLComponent;
41 ilm 20
import org.openconcerto.erp.core.supplychain.supplier.component.MouvementStockSQLComponent;
19 ilm 21
import org.openconcerto.erp.preferences.DefaultNXProps;
61 ilm 22
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
18 ilm 23
import org.openconcerto.sql.Configuration;
24
import org.openconcerto.sql.element.SQLComponent;
25
import org.openconcerto.sql.element.SQLElement;
19 ilm 26
import org.openconcerto.sql.model.SQLBackgroundTableCache;
18 ilm 27
import org.openconcerto.sql.model.SQLBase;
61 ilm 28
import org.openconcerto.sql.model.SQLField;
19 ilm 29
import org.openconcerto.sql.model.SQLInjector;
18 ilm 30
import org.openconcerto.sql.model.SQLRow;
19 ilm 31
import org.openconcerto.sql.model.SQLRowListRSH;
18 ilm 32
import org.openconcerto.sql.model.SQLRowValues;
19 ilm 33
import org.openconcerto.sql.model.SQLSelect;
18 ilm 34
import org.openconcerto.sql.model.SQLTable;
19 ilm 35
import org.openconcerto.sql.model.Where;
61 ilm 36
import org.openconcerto.sql.preferences.SQLPreferences;
19 ilm 37
import org.openconcerto.sql.users.UserManager;
18 ilm 38
import org.openconcerto.sql.view.EditFrame;
39
import org.openconcerto.sql.view.EditPanel;
19 ilm 40
import org.openconcerto.sql.view.EditPanel.EditMode;
41
import org.openconcerto.sql.view.list.RowValuesTableModel;
42
import org.openconcerto.ui.preferences.DefaultProps;
43
import org.openconcerto.utils.CollectionMap;
18 ilm 44
import org.openconcerto.utils.ExceptionHandler;
45
 
46
import java.sql.SQLException;
47
import java.util.ArrayList;
19 ilm 48
import java.util.Arrays;
18 ilm 49
import java.util.List;
50
 
61 ilm 51
import javax.swing.JOptionPane;
19 ilm 52
import javax.swing.SwingUtilities;
18 ilm 53
 
61 ilm 54
import org.apache.commons.dbutils.handlers.ArrayListHandler;
55
 
18 ilm 56
public class MouvementStockSQLElement extends ComptaSQLConfElement {
57
 
58
    public MouvementStockSQLElement() {
59
        super("MOUVEMENT_STOCK", "un mouvement de stock", "mouvements de stock");
60
    }
61
 
62
    protected List<String> getListFields() {
63
        final List<String> l = new ArrayList<String>();
64
        l.add("DATE");
65
        l.add("NOM");
66
        l.add("ID_ARTICLE");
67
        l.add("QTE");
68
        return l;
69
    }
70
 
71
    protected List<String> getComboFields() {
72
        final List<String> l = new ArrayList<String>();
73
        l.add("NOM");
74
        l.add("QTE");
75
        return l;
76
    }
77
 
78
    /*
79
     * (non-Javadoc)
80
     *
81
     * @see org.openconcerto.devis.SQLElement#getComponent()
82
     */
83
    public SQLComponent createComponent() {
41 ilm 84
        return new MouvementStockSQLComponent(this);
18 ilm 85
    }
86
 
87
    @Override
88
    protected void archive(SQLRow row, boolean cutLinks) throws SQLException {
89
        super.archive(row, cutLinks);
19 ilm 90
        updateStock(Arrays.asList(row.getID()), true);
18 ilm 91
    }
92
 
61 ilm 93
    // public CollectionMap<SQLRow, List<SQLRowValues>> updateStock(List<Integer> ids) {
94
    // return updateStock(ids, false);
95
    // }
96
 
97
    private final SQLTable sqlTableArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ARTICLE");
98
 
99
    /**
100
     * Ajout des mouvements de Stock
101
     *
102
     * @param rowOrigin SQLRow de la piece d'origine (ex : BL)
103
     * @param eltTable SQLTable des éléments de la pièce (ex : element du BL)
104
     * @param label label pour les mouvements de stocks
105
     * @param entry true si c'est une entrée de stock
106
     *
107
     */
108
    public void createMouvement(SQLRow rowOrigin, SQLTable eltTable, StockLabel label, boolean entry) {
109
 
110
        // On récupére les articles qui composent la piéce
111
        SQLSelect selEltfact = new SQLSelect(rowOrigin.getTable().getBase());
112
        selEltfact.addSelectStar(eltTable);
113
        selEltfact.setWhere(new Where((SQLField) eltTable.getForeignKeys(rowOrigin.getTable()).toArray()[0], "=", rowOrigin.getID()));
114
 
115
        List<SQLRow> lElt = SQLRowListRSH.execute(selEltfact);
116
 
117
        final boolean modeAvance = DefaultNXProps.getInstance().getBooleanValue("ArticleModeVenteAvance", false);
118
        SQLPreferences prefs = new SQLPreferences(eltTable.getDBRoot());
119
        final boolean createArticle = prefs.getBoolean(GestionArticleGlobalPreferencePanel.CREATE_ARTICLE_AUTO, true);
120
 
121
        if (lElt != null) {
122
            List<Integer> l = new ArrayList<Integer>();
123
            for (SQLRow rowElt : lElt) {
124
                SQLRow rowArticleAssocie = (rowElt.getTable().contains("ID_ARTICLE") ? rowElt.getForeign("ID_ARTICLE") : null);
125
 
126
                int idArticle;
127
 
128
                // Si on a bien sélectionné un article ou qu'il y a un code de saisi
129
                if ((rowArticleAssocie != null && !rowArticleAssocie.isUndefined()) || rowElt.getString("CODE").trim().length() > 0) {
130
 
131
                    // Si l'article est à créer ou le lien est à refaire (ancienne version saisie
132
                    // sans ID_ARTICLE en BD)
133
                    if (rowArticleAssocie == null || rowArticleAssocie.isUndefined()) {
134
                        // on récupére l'article qui lui correspond
135
                        SQLRowValues rowArticle = new SQLRowValues(sqlTableArticle);
136
                        for (SQLField field : sqlTableArticle.getFields()) {
137
                            if (rowElt.getTable().getFieldsName().contains(field.getName())) {
138
                                rowArticle.put(field.getName(), rowElt.getObject(field.getName()));
139
                            }
140
                        }
141
                        // rowArticle.loadAllSafe(rowEltFact);
142
                        if (modeAvance)
143
                            idArticle = ReferenceArticleSQLElement.getIdForCNM(rowArticle, createArticle);
144
                        else {
145
                            idArticle = ReferenceArticleSQLElement.getIdForCN(rowArticle, createArticle);
146
                        }
147
                        if (idArticle > 0 && idArticle != sqlTableArticle.getUndefinedID()) {
148
                            SQLRowValues rowVals = rowElt.asRowValues();
149
                            rowVals.put("ID_ARTICLE", idArticle);
150
                            try {
151
                                rowVals.update();
152
                            } catch (SQLException exn) {
153
                                // TODO Bloc catch auto-généré
154
                                exn.printStackTrace();
155
                            }
156
                        }
157
                    } else {
158
                        idArticle = rowArticleAssocie.getID();
159
                    }
160
 
161
                    // on crée un mouvement de stock pour chacun des articles
162
                    SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
163
                    SQLRowValues rowVals = new SQLRowValues(eltMvtStock.getTable());
164
                    if (entry) {
165
                        rowVals.put("QTE", (rowElt.getInt("QTE")));
166
                    } else {
167
                        rowVals.put("QTE", -(rowElt.getInt("QTE")));
168
                    }
169
                    rowVals.put("NOM", label.getLabel(rowOrigin, rowElt));
170
                    rowVals.put("IDSOURCE", rowOrigin.getID());
171
                    rowVals.put("SOURCE", rowOrigin.getTable().getName());
172
                    rowVals.put("ID_ARTICLE", idArticle);
173
                    rowVals.put("DATE", rowOrigin.getObject("DATE"));
174
                    try {
175
                        SQLRow row = rowVals.insert();
176
                        l.add(row.getID());
177
                    } catch (SQLException e) {
178
                        e.printStackTrace();
179
                    }
180
                }
181
            }
182
            CollectionMap<SQLRow, List<SQLRowValues>> map = updateStock(l, false);
183
            if (map.keySet().size() > 0) {
184
                if (!rowOrigin.getTable().contains("ID_TARIF")) {
185
                    System.err.println("Attention la table " + rowOrigin.getTable().getName()
186
                            + " ne contient pas le champ ID_TARIF. La création automatique d'une commande fournisseur est donc impossible!");
187
                    Thread.dumpStack();
188
                } else {
189
                    if (JOptionPane.showConfirmDialog(null, "Certains articles sont en dessous du stock minimum.\n Voulez créer une commande?") == JOptionPane.YES_OPTION) {
190
                        MouvementStockSQLElement.createCommandeF(map, rowOrigin.getForeignRow("ID_TARIF").getForeignRow("ID_DEVISE"));
191
                    }
192
                }
193
            }
194
        }
18 ilm 195
    }
196
 
197
    /**
198
     * Mise à jour des stocks ajoute la quantité si archive est à false
199
     *
200
     * @param id mouvement stock
201
     * @param archive
202
     */
61 ilm 203
    public CollectionMap<SQLRow, List<SQLRowValues>> updateStock(List<Integer> ids, boolean archive) {
19 ilm 204
        CollectionMap<SQLRow, List<SQLRowValues>> map = new CollectionMap<SQLRow, List<SQLRowValues>>();
205
        SQLTable tableCmdElt = Configuration.getInstance().getBase().getTable("COMMANDE_ELEMENT");
206
        for (Integer id : ids) {
18 ilm 207
 
19 ilm 208
            // Mise à jour des stocks
209
            SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
210
            SQLRow rowMvtStock = eltMvtStock.getTable().getRow(id);
18 ilm 211
 
19 ilm 212
            SQLTable sqlTableArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ARTICLE");
213
            SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement(sqlTableArticle);
214
            SQLElement eltStock = Configuration.getInstance().getDirectory().getElement("STOCK");
215
            final SQLRow rowArticle = rowMvtStock.getForeignRow("ID_ARTICLE");
216
            SQLRow rowStock = rowArticle.getForeignRow(("ID_STOCK"));
18 ilm 217
 
19 ilm 218
            float qte = rowStock.getFloat("QTE_REEL");
219
            float qteMvt = rowMvtStock.getFloat("QTE");
18 ilm 220
 
19 ilm 221
            SQLRowValues rowVals = new SQLRowValues(eltStock.getTable());
18 ilm 222
 
19 ilm 223
            float qteNvlle;
224
            if (archive) {
225
                qteNvlle = qte - qteMvt;
226
            } else {
227
                qteNvlle = qte + qteMvt;
228
            }
229
            rowVals.put("QTE_REEL", qteNvlle);
18 ilm 230
 
19 ilm 231
            try {
232
                if (rowStock.getID() <= 1) {
233
                    SQLRow row = rowVals.insert();
234
                    SQLRowValues rowValsArt = new SQLRowValues(eltArticle.getTable());
235
                    rowValsArt.put("ID_STOCK", row.getID());
236
 
237
                    final int idArticle = rowArticle.getID();
238
                    if (idArticle > 1) {
239
                        rowValsArt.update(idArticle);
240
                    }
241
                } else {
242
                    rowVals.update(rowStock.getID());
18 ilm 243
                }
19 ilm 244
            } catch (SQLException e) {
245
 
246
                ExceptionHandler.handle("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"));
247
                e.printStackTrace();
18 ilm 248
            }
249
 
19 ilm 250
            DefaultProps props = DefaultNXProps.getInstance();
251
            String stockMin = props.getStringProperty("ArticleStockMin");
252
            Boolean bStockMin = !stockMin.equalsIgnoreCase("false");
253
            boolean gestionStockMin = (bStockMin == null || bStockMin.booleanValue());
254
            if (!archive && rowArticle.getTable().getFieldsName().contains("QTE_MIN") && gestionStockMin && qteNvlle < rowArticle.getInt("QTE_MIN")) {
255
                // final float qteShow = qteNvlle;
256
                SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
257
                SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticle));
25 ilm 258
                rowValsElt.put("ID_STYLE", 2);
19 ilm 259
                rowValsElt.put("QTE", Math.round(rowArticle.getInt("QTE_MIN") - qteNvlle));
260
                rowValsElt.put("ID_TAXE", rowValsElt.getObject("ID_TAXE"));
261
                rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
262
                rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * rowValsElt.getInt("QTE"));
263
                rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
264
 
265
                map.put(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
41 ilm 266
 
19 ilm 267
            }
18 ilm 268
        }
19 ilm 269
        return map;
18 ilm 270
    }
271
 
19 ilm 272
    public static void createCommandeF(final CollectionMap<SQLRow, List<SQLRowValues>> col, final SQLRow rowDevise) {
273
 
274
        if (col.keySet().size() > 0) {
275
            SwingUtilities.invokeLater(new Runnable() {
276
                @Override
277
                public void run() {
278
 
41 ilm 279
                    final SQLElement commande = Configuration.getInstance().getDirectory().getElement("COMMANDE");
19 ilm 280
                    for (SQLRow fournisseur : col.keySet()) {
281
 
282
                        // On regarde si il existe une commande en cours existante
41 ilm 283
                        final SQLSelect sel = new SQLSelect(commande.getTable().getBase());
19 ilm 284
                        sel.addSelectStar(commande.getTable());
285
                        Where w = new Where(commande.getTable().getField("EN_COURS"), "=", Boolean.TRUE);
286
                        w = w.and(new Where(commande.getTable().getField("ID_FOURNISSEUR"), "=", fournisseur.getID()));
287
                        sel.setWhere(w);
288
 
41 ilm 289
                        final List<SQLRow> rowsCmd = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
19 ilm 290
 
291
                        SQLRow commandeExistante = null;
292
                        if (rowsCmd != null && rowsCmd.size() > 0) {
293
                            commandeExistante = rowsCmd.get(0);
294
                        }
295
 
296
                        EditFrame frame;
297
                        CommandeSQLComponent cmp;
298
 
299
                        if (commandeExistante != null) {
300
                            frame = new EditFrame(commande, EditMode.MODIFICATION);
301
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
302
                            cmp.select(commandeExistante);
303
                        } else {
304
                            frame = new EditFrame(commande);
305
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
41 ilm 306
                            final SQLRowValues rowVals = new SQLRowValues(commande.getTable());
307
                            final SQLElement eltComm = Configuration.getInstance().getDirectory().getElement("COMMERCIAL");
19 ilm 308
                            int idUser = UserManager.getInstance().getCurrentUser().getId();
309
                            SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));
310
 
311
                            if (rowsComm != null) {
312
                                rowVals.put("ID_COMMERCIAL", rowsComm.getID());
313
                            }
314
                            rowVals.put("ID_FOURNISSEUR", fournisseur.getID());
315
                            if (rowDevise != null) {
316
                                rowVals.put("ID_DEVISE", rowDevise.getID());
317
                            }
318
                            cmp.select(rowVals);
319
                            cmp.getRowValuesTable().getRowValuesTable().getRowValuesTableModel().clearRows();
320
                        }
321
 
41 ilm 322
                        final RowValuesTableModel model = cmp.getRowValuesTable().getRowValuesTable().getRowValuesTableModel();
19 ilm 323
                        for (SQLRowValues rowValsElt : (List<SQLRowValues>) col.get(fournisseur)) {
324
                            SQLRowValues rowValsMatch = null;
325
                            int index = 0;
326
 
327
                            for (int i = 0; i < model.getRowCount(); i++) {
41 ilm 328
                                final SQLRowValues rowValsCmdElt = model.getRowValuesAt(i);
19 ilm 329
                                if (ReferenceArticleSQLElement.isReferenceEquals(rowValsCmdElt, rowValsElt)) {
330
                                    rowValsMatch = rowValsCmdElt;
331
                                    index = i;
332
                                    break;
333
                                }
334
                            }
335
                            if (rowValsMatch != null) {
41 ilm 336
                                final int qte = rowValsMatch.getInt("QTE");
19 ilm 337
                                model.putValue(qte + rowValsElt.getInt("QTE"), index, "QTE");
338
                            } else {
339
                                model.addRow(rowValsElt);
340
                            }
341
                        }
342
 
343
                        frame.pack();
344
                        frame.setVisible(true);
345
                    }
346
                }
347
            });
348
        }
349
 
350
    }
351
 
18 ilm 352
    public static final void showSource(int id) {
41 ilm 353
        final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
354
        final SQLTable tableMvt = base.getTable("MOUVEMENT_STOCK");
355
        final String stringTableSource = tableMvt.getRow(id).getString("SOURCE");
356
        final EditFrame f;
18 ilm 357
        if (id != 1) {
358
            // Si une source est associée on l'affiche en readonly
359
            if (stringTableSource.trim().length() != 0 && tableMvt.getRow(id).getInt("IDSOURCE") != 1) {
360
                f = new EditFrame(Configuration.getInstance().getDirectory().getElement(stringTableSource), EditPanel.READONLY);
361
                f.selectionId(tableMvt.getRow(id).getInt("IDSOURCE"));
362
            } else {
363
                // Sinon on affiche le mouvement de stock
364
                f = new EditFrame(Configuration.getInstance().getDirectory().getElement(tableMvt), EditPanel.READONLY);
365
                f.selectionId(id);
366
            }
367
            f.pack();
368
            f.setVisible(true);
369
        } else {
370
            System.err.println("Aucun mouvement associé, impossible de modifier ou d'accéder à la source de cette ecriture!");
371
        }
372
    }
57 ilm 373
 
374
    @Override
375
    protected String createCode() {
376
        return createCodeFromPackage() + ".transaction";
377
    }
18 ilm 378
}