OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Rev 180 | 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.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.request.UpdateBuilder;
import org.openconcerto.utils.ListMap;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Représente un article avec son stock
 * 
 * @author Utilisateur
 * 
 */
public class StockItem {

    public enum TypeStockMouvement {
        REEL, THEORIQUE, REEL_THEORIQUE, RETOUR
    };

    private double realQty, virtualQty, receiptQty, deliverQty;
    public SQLRowAccessor article, stock;

    List<StockItemComponent> components = new ArrayList<StockItemComponent>();

    public StockItem(SQLRowAccessor article, SQLRowAccessor stock) {
        this.article = article;
        this.stock = stock;
        this.realQty = stock.getFloat("QTE_REEL");
        this.virtualQty = stock.getFloat("QTE_TH");
        this.receiptQty = stock.getFloat("QTE_RECEPT_ATTENTE");
        this.deliverQty = stock.getFloat("QTE_LIV_ATTENTE");
    }

    public void updateQty(double qty, TypeStockMouvement t) {
        updateQty(qty, t, false);
    }

    public void setDeliverQty(double deliverQty) {
        this.deliverQty = deliverQty;
    }

    public void setRealQty(double realQty) {
        this.realQty = realQty;
    }

    public void setReceiptQty(double receiptQty) {
        this.receiptQty = receiptQty;
    }

    public void setVirtualQty(double virtualQty) {
        this.virtualQty = virtualQty;
    }

    public SQLRowAccessor getArticle() {
        return article;
    };

    public void addItemComponent(StockItemComponent item) {
        this.components.add(item);
    };

    public boolean updateQtyFromChildren() throws IllegalArgumentException {
        if (components.size() == 0) {
            if (this.article.isUndefined()) {
                return false;
            }
            String code = "";
            if (this.article != null && this.article.getFields().contains("CODE") && this.article.getString("CODE") != null) {
                code = this.article.getString("CODE");
            }
            System.err.println("Impossible de mettre à jour le stock, l'articel n'est pas une nomenclature " + code);
            return false;

        }
        StockItemComponent comp = components.get(0);
        double real = comp.getItem().getRealQty() == 0 ? 0 : Math.ceil(comp.getItem().getRealQty() / (comp.getQty() * comp.getQtyUnit().doubleValue()));
        double virtual = comp.getItem().getVirtualQty() == 0 ? 0 : Math.ceil(comp.getItem().getVirtualQty() / (comp.getQty() * comp.getQtyUnit().doubleValue()));
        for (StockItemComponent stockItemComponent : components) {
            real = Math.min(real, stockItemComponent.getItem().getRealQty() == 0 ? 0
                    : Math.ceil(stockItemComponent.getItem().getRealQty() / (stockItemComponent.getQty() * stockItemComponent.getQtyUnit().doubleValue())));
            virtual = Math.min(virtual, stockItemComponent.getItem().getVirtualQty() == 0 ? 0
                    : Math.ceil(stockItemComponent.getItem().getVirtualQty() / (stockItemComponent.getQty() * stockItemComponent.getQtyUnit().doubleValue())));

        }
        // La quantité du kit ne peut être négative
        this.realQty = Math.max(0, real);
        this.virtualQty = Math.max(0, virtual);
        return true;
    }

    public void fillCommandeFournisseur(ListMap<SQLRow, SQLRowValues> cmd) {
        // TODO Gestion Stock Min par depot
        SQLPreferences prefs = new SQLPreferences(article.getTable().getDBRoot());
        boolean gestionStockMin = prefs.getBoolean(GestionArticleGlobalPreferencePanel.WARNING_STOCK_MIN, true);
        if (gestionStockMin && stock.getObject("QTE_MIN") != null && getRealQty() < stock.getFloat("QTE_MIN")) {
            // final float qteShow = qteNvlle;
            SQLInjector inj = SQLInjector.getInjector(article.getTable(), article.getTable().getTable("COMMANDE_ELEMENT"));
            final SQLRow asRow = article.asRow();
            SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(asRow));
            rowValsElt.put("ID_STYLE", 2);
            final SQLRowAccessor unite = article.getForeign("ID_UNITE_VENTE");
            final double qteElt = stock.getFloat("QTE_MIN") - getRealQty();
            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));

            cmd.add(asRow.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
        }

    }

    /**
     * Mise à jour des quantités de stocks. 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
     * 
     * @param qty quantité à ajouter ou à soustraire
     * @param t Type de stock à mettre à jour (réel ou virtuel)
     * @param archive annulation du stock
     */
    public void updateQty(double qty, TypeStockMouvement t, boolean archive) {

        if (t == TypeStockMouvement.REEL || t == TypeStockMouvement.REEL_THEORIQUE || t == TypeStockMouvement.RETOUR) {
            final double qteNvlle;
            final double qteOrigin = this.realQty;
            if (archive) {
                qteNvlle = qteOrigin - qty;
                if (t != TypeStockMouvement.RETOUR) {
                    // Réception
                    if (qty > 0) {
                        this.receiptQty += qty;
                    } else {
                        // Livraison
                        this.deliverQty -= qty;
                    }
                }
            } else {
                qteNvlle = qteOrigin + qty;
                if (t != TypeStockMouvement.RETOUR) {
                    // Réception
                    if (qty > 0) {
                        this.receiptQty -= qty;
                    } else {
                        // Livraison
                        this.deliverQty += qty;
                    }
                }
            }

            this.realQty = qteNvlle;

        }

        if (t == TypeStockMouvement.THEORIQUE || t == TypeStockMouvement.REEL_THEORIQUE || t == TypeStockMouvement.RETOUR) {

            // THEORIQUE
            final double qteNvlle;
            final double qteOrigin = this.virtualQty;
            if (archive) {
                qteNvlle = qteOrigin - qty;
                if (t != TypeStockMouvement.RETOUR) {
                    // Réception
                    if (qty > 0) {
                        this.receiptQty -= qty;
                    } else {
                        // Livraison
                        this.deliverQty += qty;
                    }
                }
            } else {
                qteNvlle = qteOrigin + qty;
                if (t != TypeStockMouvement.RETOUR) {
                    // Réception
                    if (qty > 0) {
                        this.receiptQty += qty;
                    } else {
                        // Livraison
                        this.deliverQty -= qty;
                    }
                }
            }

            this.virtualQty = qteNvlle;
        }
    }

    public double getDeliverQty() {
        return deliverQty;
    }

    public double getRealQty() {
        return realQty;
    }

    public double getReceiptQty() {
        return receiptQty;
    }

    public double getVirtualQty() {
        return virtualQty;
    }

    public boolean isStockInit() {
        return this.stock != null && !this.stock.isUndefined();
    }

    public void clearStockValues() {
        this.realQty = 0;
        this.deliverQty = 0;
        this.receiptQty = 0;
        this.virtualQty = 0;
    }

    public String getUpdateRequest() {
        final SQLTable stockTable = this.stock.getTable();
        UpdateBuilder update = new UpdateBuilder(stockTable);
        update.setWhere(new Where(stockTable.getKey(), "=", this.stock.getID()));
        update.setObject("QTE_REEL", getRealQty());
        update.setObject("QTE_TH", getVirtualQty());
        update.setObject("QTE_LIV_ATTENTE", getDeliverQty());
        update.setObject("QTE_RECEPT_ATTENTE", getReceiptQty());
        return update.asString();
    }

}