OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 182 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011-2019 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.sales.pos.model;

import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.QuickOrderedMap;
import org.openconcerto.utils.Tuple2;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Article {
    private Categorie s;
    private String name;
    private boolean additionalCopyRequested = false;
    private BigDecimal priceTTC;
    private int idTaxe;
    private BigDecimal priceHT;
    private String barCode = "empty barcode";
    private String code = "";
    private BigDecimal discount_pct = BigDecimal.ZERO;
    private BigDecimal ecotaxe = BigDecimal.ZERO;
    private final int id;
    // unité de vente (null si à la pièce)
    private String salesUnit;
    private static Map<String, List<Article>> codes = new HashMap<>();

    // type de declinaison : nom de la déclinaison et ordre (ex "taille":"45 / 5.5",
    // "couleur","rouge / 2.05"), null si pas de declinaison
    private QuickOrderedMap<String, Tuple2<String, BigDecimal>> declinaisons;

    List<TarifQuantite> tarifs;
    private String declinaison;
    private String articlePereNom = null;

    public Article(Categorie s1, String string, int id) {
        this.s = s1;
        this.id = id;
        this.name = string;
        s1.addArticle(this);
    }

    public Article(Article a) {
        this.s = a.s;
        this.code = a.code;
        this.name = a.name;
        this.priceTTC = a.priceTTC;
        this.idTaxe = a.idTaxe;
        this.priceHT = a.priceHT;
        this.barCode = a.barCode;
        this.id = a.id;
        this.salesUnit = a.salesUnit;
        this.discount_pct = a.discount_pct;
        this.ecotaxe = a.ecotaxe;

        this.s.addArticle(this);
        final QuickOrderedMap<String, Tuple2<String, BigDecimal>> decl = a.getDeclinaisons();
        if (decl != null) {
            final int size = decl.size();
            this.declinaisons = new QuickOrderedMap<>(size);
            for (int i = 0; i < size; i++) {
                this.declinaisons.put(decl.getKey(i), decl.getValue(i));
            }
        }
    }

    public void setTarifsPromotion(List<TarifQuantite> list) {
        this.tarifs = new ArrayList<>();
        for (TarifQuantite t : list) {
            if (t.getIdArticle() == this.id) {
                this.tarifs.add(t);
            }
        }
        Collections.sort(this.tarifs, new Comparator<TarifQuantite>() {

            @Override
            public int compare(TarifQuantite o1, TarifQuantite o2) {
                return o1.getQuantite() - o2.getQuantite();
            }

        });
    }

    public TarifQuantite getTarifPromotionForQuantity(int qty) {
        if (this.tarifs == null || this.tarifs.isEmpty()) {
            return null;
        }
        TarifQuantite result = null;
        for (final TarifQuantite t : this.tarifs) {
            if (t.getQuantite() > qty) {
                break;
            }
            result = t;
        }
        return result;
    }

    public void addDeclinaison(String key, String value, BigDecimal ordreDeclinaison) {
        if (this.declinaisons == null) {
            this.declinaisons = new QuickOrderedMap<>(5);
        }
        this.declinaisons.put(key, Tuple2.create(value, ordreDeclinaison));
    }

    public QuickOrderedMap<String, Tuple2<String, BigDecimal>> getDeclinaisons() {
        return this.declinaisons;
    }

    public void setArticlePereNom(String articlePereNom) {
        this.articlePereNom = articlePereNom;
    }

    public String getArticlePereNom() {
        return this.articlePereNom;
    }

    public boolean isPromotion() {
        return this.tarifs != null && !this.tarifs.isEmpty();
    }

    public boolean isAdditionalCopyRequested() {
        return this.additionalCopyRequested;
    }

    public void setAdditionalCopyRequested(boolean additionalCopyRequested) {
        this.additionalCopyRequested = additionalCopyRequested;
    }

    public int getId() {
        return this.id;
    }

    public BigDecimal getPriceWithoutTax() {
        return getPriceWithoutTax(false);
    }

    public BigDecimal getPriceWithoutTax(boolean with_discount) {
        if (with_discount)
            return this.priceHT.multiply(BigDecimal.ONE.subtract(getDiscountPct()));
        return this.priceHT;
    }

    public BigDecimal getPriceWithoutTax(BigDecimal qty) {
        return getPriceWithoutTax(qty, false);
    }

    public BigDecimal getPriceWithoutTax(BigDecimal qty, boolean withDiscount) {
        BigDecimal price = this.priceHT;
        if (getSalesUnit() == null) {
            // Promotion
            final TarifQuantite tarifPromotionForQuantity = getTarifPromotionForQuantity(qty.intValue());
            if (tarifPromotionForQuantity != null) {
                price = tarifPromotionForQuantity.getPrixHT();
            }
        }

        if (withDiscount) {
            price = price.multiply(BigDecimal.ONE.subtract(getDiscountPct()));
        }
        return price;

    }

    public void setPriceWithoutTax(BigDecimal priceHTInCents) {
        this.priceHT = priceHTInCents;
    }

    public int getIdTaxe() {
        return this.idTaxe;
    }

    public void setIdTaxe(int idTaxe) {
        this.idTaxe = idTaxe;
    }

    public void setBarCode(String bar) {
        this.barCode = bar;
        List<Article> list = codes.get(bar);
        if (list == null) {
            list = new ArrayList<>();
            codes.put(bar, list);
        }
        list.add(this);
    }

    public void setPriceWithTax(BigDecimal priceInCents) {
        this.priceTTC = priceInCents;
    }

    public BigDecimal getPriceWithTax(BigDecimal quantity) {
        return getPriceWithTax(quantity, false);
    }

    public BigDecimal getPriceWithTax(BigDecimal qty, boolean withDiscount) {
        BigDecimal price = this.priceTTC;
        if (getSalesUnit() == null) {
            // Promotion
            final TarifQuantite tarifPromotionForQuantity = getTarifPromotionForQuantity(qty.intValue());
            if (tarifPromotionForQuantity != null) {
                price = tarifPromotionForQuantity.getPrixTTC();
            }
        }

        if (withDiscount) {
            price = price.multiply(BigDecimal.ONE.subtract(getDiscountPct()));
        }
        return price;
    }

    public String getName() {
        return this.name;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getCode() {
        return this.code;
    };

    public String getBarCode() {
        return this.barCode;
    }

    public Categorie getCategorie() {
        return this.s;
    }

    @Override
    public String toString() {
        if (this.declinaisons != null) {
            return "Article:" + this.code + " | " + this.name + " " + this.priceTTC + " cents" + "(HT:" + this.priceHT + ") " + getSalesUnit() + " discount:" + getDiscountPct();
        }
        return "Article:" + this.code + " | " + this.name + "  [" + this.declinaisons + "] : " + this.priceTTC + " cents" + "(HT:" + this.priceHT + ") " + getSalesUnit() + " discount:"
                + getDiscountPct();
    }

    public static List<Article> getArticleFromBarcode(String code) {
        return codes.get(code);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        return this.id == ((Article) obj).id;
    }

    @Override
    public int hashCode() {
        return this.id;
    }

    public void updatePriceWithoutTax(BigDecimal ht) {
        this.priceHT = ht;
        this.priceTTC = computePriceWithTax(ht, this.getIdTaxe());
    }

    public static BigDecimal computePriceWithTax(BigDecimal ht, int idTaxe) {
        final BigDecimal tax = BigDecimal.valueOf(TaxeCache.getCache().getTauxFromId(idTaxe)).movePointLeft(2).add(BigDecimal.ONE);
        return ht.multiply(tax).setScale(2, RoundingMode.HALF_UP);
    }

    public static BigDecimal computePriceWithoutTax(BigDecimal ttc, int idTaxe) {
        final BigDecimal tax = BigDecimal.valueOf(TaxeCache.getCache().getTauxFromId(idTaxe)).movePointLeft(2).add(BigDecimal.ONE);
        return ttc.divide(tax, DecimalUtils.HIGH_PRECISION).setScale(6, RoundingMode.HALF_UP);
    }

    public void setSalesUnit(String name) {
        this.salesUnit = name;
    }

    public String getSalesUnit() {
        return this.salesUnit;
    }

    public void setDiscountPct(BigDecimal dsct) {
        this.discount_pct = dsct;
    }

    public BigDecimal getEcoTaxe() {
        return this.ecotaxe;
    }

    public BigDecimal getDiscountPct() {
        return this.discount_pct;
    }

    public void setEcoTaxe(BigDecimal ecotaxe) {
        this.ecotaxe = ecotaxe;
    }

    /**
     * ligne precisant la declinaison sur le ticket
     */
    public void setDeclinaison(String declinaison) {
        this.declinaison = declinaison;
    }

    public String getDeclinaison() {
        if (this.declinaison == null && this.declinaisons != null && !this.declinaisons.isEmpty()) {
            StringBuilder b = new StringBuilder();
            for (int i = 0; i < this.declinaisons.size(); i++) {
                final Tuple2<String, BigDecimal> value = this.declinaisons.getValue(i);
                if (value != null) {
                    b.append(value.get0());
                    b.append("  ");
                }
            }

            return b.toString().trim();
        }
        return this.declinaison;
    }

}