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 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.core.supplychain.stock.element;

import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
import org.openconcerto.erp.core.supplychain.order.component.CommandeSQLComponent;
import org.openconcerto.erp.core.supplychain.order.ui.CommandeItemTable;
import org.openconcerto.erp.core.supplychain.supplier.component.MouvementStockSQLComponent;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.TreesOfSQLRows;
import org.openconcerto.sql.model.SQLBackgroundTableCache;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.request.ListSQLRequest;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.ListMap;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class MouvementStockSQLElement extends ComptaSQLConfElement {

    public MouvementStockSQLElement() {
        super("MOUVEMENT_STOCK", "un mouvement de stock", "mouvements de stock");
    }

    @Override
    public ListMap<String, String> getShowAs() {
        ListMap<String, String> map = new ListMap<String, String>();
        map.putCollection("ID_STOCK", "ID_DEPOT_STOCK");
        return map;
    }

    protected List<String> getListFields() {
        final List<String> l = new ArrayList<String>();
        l.add("ID_STOCK");
        l.add("DATE");
        l.add("NOM");
        l.add("ID_ARTICLE");
        l.add("QTE");
        l.add("REEL");
        return l;
    }

    protected List<String> getComboFields() {
        final List<String> l = new ArrayList<String>();
        l.add("NOM");
        l.add("QTE");
        return l;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.openconcerto.devis.SQLElement#getComponent()
     */
    public SQLComponent createComponent() {
        return new MouvementStockSQLComponent(this);
    }

    @Override
    protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {
        super.archive(trees, cutLinks);
        updateStock(trees.getRows(), true);

    }

    /**
     * Mise à jour des stocks ajoute la quantité si archive est à false
     * 
     * @param id mouvement stock
     * @param archive
     * @throws SQLException
     */
    public ListMap<SQLRow, SQLRowValues> updateStock(Collection<SQLRow> rowsMvt, boolean archive) throws SQLException {
        // FIXME: if (SwingUtilities.isEventDispatchThread()) {
        // throw new IllegalStateException("This method must be called outside of EDT");
        // }
        // Stock Reel : inc/dec QTE_REEL, inc/dec QTE_LIV_ATTENTE/inc/dec
        // QTE_RECEPT_ATTENTE
        // Stock Th : inc/dec QTE_TH, inc/dec QTE_LIV_ATTENTE/inc/dec
        // QTE_RECEPT_ATTENTE

        final ListMap<SQLRow, SQLRowValues> map = new ListMap<>();
        final SQLTable tableCommandeElement = Configuration.getInstance().getBase().getTable("COMMANDE_ELEMENT");
        final SQLElement elementStock = Configuration.getInstance().getDirectory().getElement("STOCK");

        for (SQLRow rowMvtStock : rowsMvt) {

            boolean retour = rowMvtStock.getString("SOURCE") == null || rowMvtStock.getString("SOURCE").startsWith("AVOIR_CLIENT");
            // Mise à jour des stocks

            final SQLRow rowArticle = rowMvtStock.getForeignRow("ID_ARTICLE");

            SQLRow rowStock = rowMvtStock.getForeignRow(("ID_STOCK"));
            if (rowStock == null || rowStock.isUndefined()) {
                rowStock = rowArticle.getForeign("ID_STOCK");
            }

            if (rowMvtStock.getBoolean("REEL")) {
                float qte = rowStock.getFloat("QTE_REEL");
                float qteMvt = rowMvtStock.getFloat("QTE");

                SQLRowValues rowVals = new SQLRowValues(elementStock.getTable());

                float qteNvlle;
                float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
                float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
                if (archive) {
                    qteNvlle = qte - qteMvt;
                    if (!retour) {
                        // Réception
                        if (qteMvt > 0) {
                            qteNvlleEnAttenteRecept += qteMvt;
                        } else {
                            // Livraison
                            qteNvlleEnAttenteExp -= qteMvt;
                        }
                    }
                } else {
                    qteNvlle = qte + qteMvt;
                    if (!retour) {
                        // Réception
                        if (qteMvt > 0) {
                            qteNvlleEnAttenteRecept -= qteMvt;
                        } else {
                            // Livraison
                            qteNvlleEnAttenteExp += qteMvt;
                        }
                    }
                }
                rowVals.put("QTE_REEL", qteNvlle);
                rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
                rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);

                try {
                    rowVals.update(rowStock.getID());

                    SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
                    boolean gestionStockMin = prefs.getBoolean(GestionArticleGlobalPreferencePanel.WARNING_STOCK_MIN, true);

                    if (!archive && gestionStockMin && rowStock.getObject("QTE_MIN") != null && qteNvlle < rowStock.getFloat("QTE_MIN")) {
                        // final float qteShow = qteNvlle;
                        SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCommandeElement);
                        SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticle));
                        rowValsElt.put("ID_STYLE", 2);
                        final SQLRow unite = rowArticle.getForeign("ID_UNITE_VENTE");
                        final float qteElt = rowStock.getFloat("QTE_MIN") - qteNvlle;
                        if (unite.isUndefined() || unite.getBoolean("A_LA_PIECE")) {
                            rowValsElt.put("QTE", Math.round(qteElt));
                            rowValsElt.put("QTE_UNITAIRE", BigDecimal.ONE);
                        } else {
                            rowValsElt.put("QTE", 1);
                            rowValsElt.put("QTE_UNITAIRE", new BigDecimal(qteElt));
                        }
                        rowValsElt.put("ID_TAXE", rowValsElt.getObject("ID_TAXE"));
                        rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * qteElt);
                        rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * qteElt);
                        rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
                        map.add(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
                    }
                } catch (SQLException e) {
                    throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
                }
            } else {
                float qte = rowStock.getFloat("QTE_TH");
                float qteMvt = rowMvtStock.getFloat("QTE");

                SQLRowValues rowVals = new SQLRowValues(elementStock.getTable());

                float qteNvlle;
                float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
                float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");

                if (archive) {
                    qteNvlle = qte - qteMvt;
                    if (!retour) {

                        // CommandeF
                        if (qteMvt > 0) {
                            qteNvlleEnAttenteRecept -= qteMvt;
                        } else {
                            // CommanceC
                            qteNvlleEnAttenteExp += qteMvt;
                        }
                    }
                } else {
                    qteNvlle = qte + qteMvt;
                    if (!retour) {

                        // CommandeF
                        if (qteMvt > 0) {
                            qteNvlleEnAttenteRecept += qteMvt;
                        } else {
                            // CommanceC
                            qteNvlleEnAttenteExp -= qteMvt;
                        }
                    }
                }
                rowVals.put("QTE_TH", qteNvlle);
                rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
                rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
                try {
                    rowVals.update(rowStock.getID());
                } catch (SQLException e) {
                    throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
                }
            }

        }
        return map;
    }

    public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise) {
        createCommandeF(col, rowDevise, "");
    }

    public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise, final String ref) {
        if (SwingUtilities.isEventDispatchThread()) {
            throw new IllegalStateException("This method must be called outside of EDT");
        }
        if (col.size() > 0) {

            final SQLElement commande = Configuration.getInstance().getDirectory().getElement("COMMANDE");
            Boolean useCommandeEnCours = SQLPreferences.getMemCached(commande.getTable().getDBRoot()).getBoolean(GestionCommercialeGlobalPreferencePanel.COMMANDE_FOURNISSEUR_EN_COURS, false);
            for (final Entry<SQLRow, List<SQLRowValues>> e : col.entrySet()) {
                final SQLRow fournisseur = e.getKey();
                // On regarde si il existe une commande en cours existante
                final SQLSelect sel = new SQLSelect();
                sel.addSelectStar(commande.getTable());
                Where w = new Where(commande.getTable().getField("EN_COURS"), "=", Boolean.TRUE);
                w = w.and(new Where(commande.getTable().getField("ID_FOURNISSEUR"), "=", fournisseur.getID()));
                sel.setWhere(w);

                final List<SQLRow> rowsCmd = !useCommandeEnCours ? null
                        : (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));

                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        SQLRow commandeExistante = null;
                        if (rowsCmd != null && rowsCmd.size() > 0) {
                            commandeExistante = rowsCmd.get(0);
                        }
                        EditFrame frame;
                        CommandeSQLComponent cmp;

                        if (commandeExistante != null) {
                            frame = new EditFrame(commande, EditMode.MODIFICATION);
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
                            cmp.select(commandeExistante);
                        } else {
                            frame = new EditFrame(commande);
                            cmp = (CommandeSQLComponent) frame.getSQLComponent();
                            final SQLRowValues rowVals = new SQLRowValues(commande.getTable());
                            final SQLElement eltComm = Configuration.getInstance().getDirectory().getElement("COMMERCIAL");
                            int idUser = UserManager.getInstance().getCurrentUser().getId();
                            SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));

                            if (rowsComm != null) {
                                rowVals.put("ID_COMMERCIAL", rowsComm.getID());
                            }
                            if (fournisseur != null && !fournisseur.isUndefined()) {
                                rowVals.put("ID_FOURNISSEUR", fournisseur.getID());
                            }
                            if (rowDevise != null) {
                                rowVals.put("ID_DEVISE", rowDevise.getID());
                            }
                            if (commande.getTable().contains("ID_ADRESSE")) {
                                rowVals.put("ID_ADRESSE", null);
                            }
                            rowVals.put("NOM", ref);
                            cmp.select(rowVals);
                            cmp.getRowValuesTable().getRowValuesTableModel().clearRows();
                        }

                        CommandeItemTable itemTable = cmp.getRowValuesTablePanel();

                        final RowValuesTableModel model = cmp.getRowValuesTable().getRowValuesTableModel();
                        for (SQLRowValues rowValsElt : e.getValue()) {
                            SQLRowValues rowValsMatch = null;
                            int index = 0;

                            for (int i = 0; i < model.getRowCount(); i++) {
                                final SQLRowValues rowValsCmdElt = model.getRowValuesAt(i);
                                if (ReferenceArticleSQLElement.isReferenceEquals(rowValsCmdElt, rowValsElt)) {
                                    rowValsMatch = rowValsCmdElt;
                                    index = i;
                                    break;
                                }
                            }
                            if (rowValsMatch != null) {

                                int qte = rowValsMatch.getInt("QTE");
                                BigDecimal qteUV = rowValsMatch.getBigDecimal("QTE_UNITAIRE");

                                if (rowValsMatch.getObject("ID_UNITE_VENTE") != null && rowValsMatch.getForeignID("ID_UNITE_VENTE") != UniteVenteArticleSQLElement.A_LA_PIECE) {
                                    qteUV = qteUV.multiply(new BigDecimal(qte));
                                    int qteElt = rowValsElt.getInt("QTE");
                                    BigDecimal qteUVElt = rowValsElt.getBigDecimal("QTE_UNITAIRE");
                                    qteUV = qteUV.add(qteUVElt.multiply(new BigDecimal(qteElt)));
                                    qte = 1;
                                } else {
                                    qte += rowValsElt.getInt("QTE");
                                }

                                model.putValue(qte, index, "QTE");
                                model.putValue(qteUV, index, "QTE_UNITAIRE");
                            } else {
                                model.addRow(rowValsElt);
                                if (rowValsElt.getObject("ID_ARTICLE") != null && !rowValsElt.isForeignEmpty("ID_ARTICLE")) {
                                    Object o = itemTable.tarifCompletion(rowValsElt.getForeign("ID_ARTICLE").asRow(), "PRIX_METRIQUE_HA_1");
                                    if (o != null) {
                                        model.putValue(o, model.getRowCount() - 1, "PRIX_METRIQUE_HA_1");
                                    }
                                }
                            }
                        }

                        frame.pack();
                        FrameUtil.show(frame);

                    }
                });
            }
        } else {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    JOptionPane.showMessageDialog(null, "Aucune commande à passer", "Commande fournisseur", JOptionPane.INFORMATION_MESSAGE);
                }

            });
        }

    }

    @Override
    protected void _initListRequest(ListSQLRequest req) {
        super._initListRequest(req);
        req.addToGraphToFetch("SOURCE", "IDSOURCE");
    }

    public static final void showSource(final int id) {
        if (!SwingUtilities.isEventDispatchThread()) {
            throw new IllegalStateException("This method must be called from EDT");
        }
        if (id != 1) {
            final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
            final SQLTable tableMvt = base.getTable("MOUVEMENT_STOCK");
            final String stringTableSource = tableMvt.getRow(id).getString("SOURCE");
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {

                    final EditFrame f;
                    // Si une source est associée on l'affiche en readonly
                    if (stringTableSource.trim().length() != 0 && tableMvt.getRow(id).getInt("IDSOURCE") != 1) {
                        f = new EditFrame(Configuration.getInstance().getDirectory().getElement(stringTableSource), EditPanel.READONLY);
                        f.selectionId(tableMvt.getRow(id).getInt("IDSOURCE"));
                    } else {
                        // Sinon on affiche le mouvement de stock
                        f = new EditFrame(Configuration.getInstance().getDirectory().getElement(tableMvt), EditPanel.READONLY);
                        f.selectionId(id);
                    }
                    f.pack();
                    FrameUtil.show(f);

                }
            });
        } else {
            System.err.println("Aucun mouvement associé, impossible de modifier ou d'accéder à la source de cette ecriture!");
        }
    }

    @Override
    protected String createCode() {
        return createCodeOfPackage() + ".transaction";
    }
}