OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 156 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 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.sales.product.model;
15
 
132 ilm 16
import org.openconcerto.erp.core.sales.product.model.ProductHelper.SupplierPriceField;
156 ilm 17
import org.openconcerto.erp.core.supplychain.stock.element.DepotStockSQLElement;
174 ilm 18
import org.openconcerto.sql.Configuration;
19
import org.openconcerto.sql.model.SQLField;
93 ilm 20
import org.openconcerto.sql.model.SQLRow;
21
import org.openconcerto.sql.model.SQLRowAccessor;
156 ilm 22
import org.openconcerto.sql.model.SQLRowValues;
23
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
93 ilm 24
import org.openconcerto.sql.model.SQLTable;
156 ilm 25
import org.openconcerto.sql.model.Where;
93 ilm 26
import org.openconcerto.utils.DecimalUtils;
156 ilm 27
import org.openconcerto.utils.ExceptionHandler;
93 ilm 28
 
29
import java.math.BigDecimal;
30
import java.math.RoundingMode;
156 ilm 31
import java.sql.SQLException;
93 ilm 32
import java.util.ArrayList;
33
import java.util.Calendar;
34
import java.util.Collection;
35
import java.util.Date;
36
import java.util.List;
37
 
38
public class ProductComponent {
39
    private final SQLRowAccessor product;
156 ilm 40
    private final SQLRowAccessor source;
41
    private final SQLRowAccessor stock;
93 ilm 42
    private BigDecimal qty;
132 ilm 43
    private final ProductHelper helper;
93 ilm 44
 
156 ilm 45
    public ProductComponent(SQLRowAccessor product, BigDecimal qty, SQLRowAccessor source, SQLRowAccessor stock) {
93 ilm 46
        this.product = product;
47
        this.qty = qty;
132 ilm 48
        this.helper = new ProductHelper(product.getTable().getDBRoot());
156 ilm 49
        this.source = source;
50
        this.stock = stock;
93 ilm 51
    }
52
 
53
    public SQLRowAccessor getProduct() {
54
        return product;
55
    }
56
 
156 ilm 57
    public SQLRowAccessor getSource() {
58
        return source;
59
    }
60
 
61
    public SQLRowAccessor getStock() {
62
        return stock;
63
    }
64
 
93 ilm 65
    public BigDecimal getQty() {
66
        return qty;
67
    }
68
 
69
    public void setQty(BigDecimal qty) {
70
        this.qty = qty;
71
    }
72
 
73
    public void addQty(BigDecimal b) {
74
        this.qty = qty.add(b);
75
    }
76
 
77
    /**
78
     * permet de valoriser les mouvements de stocks
79
     *
80
     * @return
81
     */
82
    public BigDecimal getPRC(Date d) {
83
        if (product.getTable().getDBRoot().contains("ARTICLE_PRIX_REVIENT")) {
132 ilm 84
            BigDecimal result = null;
85
            {
86
                SQLTable table = product.getTable().getDBRoot().getTable("ARTICLE_PRIX_REVIENT");
87
                Collection<SQLRow> prcs = product.asRow().getReferentRows(table);
93 ilm 88
 
132 ilm 89
                Date lastDate = null;
90
                final List<PriceByQty> prices = new ArrayList<PriceByQty>();
91
                for (SQLRow row : prcs) {
92
                    Calendar date = Calendar.getInstance();
93
                    if (row.getObject("DATE") != null) {
94
                        date = row.getDate("DATE");
95
                        lastDate = date.getTime();
96
                    }
97
                    prices.add(new PriceByQty(row.getLong("QTE"), row.getBigDecimal("PRIX"), date.getTime()));
93 ilm 98
                }
132 ilm 99
 
100
                result = PriceByQty.getPriceForQty(qty.setScale(0, RoundingMode.HALF_UP).intValue(), prices, d);
101
                if (result == null) {
102
                    result = PriceByQty.getPriceForQty(qty.setScale(0, RoundingMode.HALF_UP).intValue(), prices, lastDate);
156 ilm 103
                } else if (prices.size() > 0) {
104
                    result = prices.get(0).getPrice();
132 ilm 105
                }
93 ilm 106
            }
132 ilm 107
            if (result == null) {
108
                SQLTable tableATF = product.getTable().getDBRoot().getTable("ARTICLE_TARIF_FOURNISSEUR");
109
                Collection<SQLRow> atfs = product.asRow().getReferentRows(tableATF);
93 ilm 110
 
132 ilm 111
                Date lastDateATF = null;
112
                final List<PriceByQty> pricesATF = new ArrayList<PriceByQty>();
113
                for (SQLRow row : atfs) {
114
                    Calendar date = Calendar.getInstance();
115
                    if (row.getObject("DATE_PRIX") != null) {
116
                        date = row.getDate("DATE_PRIX");
117
                        lastDateATF = date.getTime();
118
                    }
119
                    pricesATF.add(new PriceByQty(row.getLong("QTE"), this.helper.getEnumPrice(row, SupplierPriceField.COEF_TRANSPORT_SIEGE), date.getTime()));
120
                }
121
 
122
                result = PriceByQty.getPriceForQty(qty.setScale(0, RoundingMode.HALF_UP).intValue(), pricesATF, d);
123
                if (result == null) {
124
                    result = PriceByQty.getPriceForQty(qty.setScale(0, RoundingMode.HALF_UP).intValue(), pricesATF, lastDateATF);
125
                    if (result == null) {
126
                        // Can occur during editing
127
                        result = BigDecimal.ZERO;
128
                    }
129
                }
93 ilm 130
            }
132 ilm 131
 
93 ilm 132
            return result;
133
        }
134
        return null;
135
    }
136
 
156 ilm 137
    public static ProductComponent createFromRowArticle(SQLRowAccessor rowArticle, SQLRowAccessor rowValsSource) {
138
        SQLRowAccessor rowStock = getStock(rowArticle, rowArticle, rowValsSource);
139
 
140
        return new ProductComponent(rowArticle, BigDecimal.ONE, rowValsSource, rowStock);
141
    }
142
 
93 ilm 143
    public static ProductComponent createFrom(SQLRowAccessor rowVals) {
156 ilm 144
        return createFrom(rowVals, 1, rowVals);
93 ilm 145
    }
146
 
156 ilm 147
    public static ProductComponent createFrom(SQLRowAccessor rowVals, SQLRowAccessor rowValsSource) {
148
        return createFrom(rowVals, 1, rowValsSource);
149
    }
93 ilm 150
 
156 ilm 151
    public static ProductComponent createFrom(SQLRowAccessor rowVals, int qteMultiple, SQLRowAccessor rowValsSource) {
152
 
153
        if (rowVals.getForeign("ID_ARTICLE") == null || rowVals.isForeignEmpty("ID_ARTICLE")) {
154
            throw new IllegalArgumentException("Aucun article associé à la row " + rowVals.getTable().getName() + " " + rowVals.getID());
155
        }
132 ilm 156
        final int qteMult = (rowVals.getTable().getName().equalsIgnoreCase("BON_DE_LIVRAISON_ELEMENT") ? rowVals.getInt("QTE_LIVREE") : rowVals.getInt("QTE"));
157
        final int qte = qteMult * qteMultiple;
93 ilm 158
        final BigDecimal qteUV = rowVals.getBigDecimal("QTE_UNITAIRE");
159
        BigDecimal qteFinal = qteUV.multiply(new BigDecimal(qte), DecimalUtils.HIGH_PRECISION);
156 ilm 160
        SQLRowAccessor rowStock = getStock(rowVals.getForeign("ID_ARTICLE"), rowVals, rowValsSource);
161
 
162
        // }
163
        // else {
164
        // rowStock = rowVals.getForeign("ID_ARTICLE").getForeign("ID_STOCK");
165
        // }
166
        return new ProductComponent(rowVals.getForeign("ID_ARTICLE"), qteFinal, rowValsSource, rowStock);
167
        // return new ProductComponent(rowVals.getForeign("ID_ARTICLE"), qteFinal);
93 ilm 168
    }
156 ilm 169
 
170
    private static SQLRowAccessor getStock(SQLRowAccessor rowValsProduct, SQLRowAccessor rowValsElt, SQLRowAccessor rowValsSource) {
171
        SQLRowAccessor rowStock = null;
174 ilm 172
        int idDepot = -1;
173
 
174
        if (rowValsProduct.getTable().getDBRoot().contains("AFFAIRE")) {
175
            SQLTable tableAff = rowValsProduct.getTable().getTable("AFFAIRE");
176
            if (tableAff.contains("ID_DEPOT_STOCK")) {
177
                if (rowValsSource.getFields().contains("ID_DEPOT_STOCK") && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
178
                    idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
179
                } else if (rowValsSource.getFields().contains("ID_AFFAIRE") && !rowValsSource.isForeignEmpty("ID_AFFAIRE")) {
180
                    SQLRowAccessor rowAff = rowValsSource.getForeign("ID_AFFAIRE");
181
                    if (rowAff.getFields().contains("ID_DEPOT_STOCK") && !rowAff.isForeignEmpty("ID_DEPOT_STOCK")) {
182
                        idDepot = rowAff.getForeignID("ID_DEPOT_STOCK");
183
                    }
184
                } else {
185
                    SQLField fieldParent = Configuration.getInstance().getDirectory().getElement(rowValsSource.getTable()).getParentForeignField();
186
                    if (fieldParent != null) {
187
                        SQLRowAccessor parent = rowValsSource.getForeign(fieldParent.getName());
188
 
189
                        if (parent.getFields().contains("ID_AFFAIRE") && !parent.isForeignEmpty("ID_AFFAIRE")) {
190
                            SQLRowAccessor rowAff = parent.getForeign("ID_AFFAIRE");
191
                            if (rowAff.getFields().contains("ID_DEPOT_STOCK") && !rowAff.isForeignEmpty("ID_DEPOT_STOCK")) {
192
                                idDepot = rowAff.getForeignID("ID_DEPOT_STOCK");
193
                            }
194
                        }
195
                    }
196
                }
197
            }
198
        }
199
 
200
        if (idDepot == -1) {
201
 
202
            if (rowValsSource.getFields().contains("ID_DEPOT_STOCK") && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
203
                idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
156 ilm 204
            } else {
174 ilm 205
                if (rowValsElt.getForeign("ID_DEPOT_STOCK") != null && !rowValsElt.isForeignEmpty("ID_DEPOT_STOCK")) {
206
                    idDepot = rowValsElt.getForeignID("ID_DEPOT_STOCK");
207
                } else {
208
                    idDepot = DepotStockSQLElement.DEFAULT_ID;
209
                    try {
210
                        rowValsElt.createEmptyUpdateRow().put("ID_DEPOT_STOCK", idDepot).commit();
211
                    } catch (SQLException e) {
212
                        ExceptionHandler.handle("Erreur lors de l'initialisation du stock!", e);
213
                    }
214
 
156 ilm 215
                }
216
            }
217
        }
218
        SQLTable stockTable = rowValsElt.getTable().getTable("STOCK");
219
        SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
220
        putRowValuesStock.putNulls(stockTable.getTable().getFieldsName());
221
 
222
        SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
223
        Where w = new Where(putRowValuesStock.getTable().getField("ID_DEPOT_STOCK"), "=", idDepot);
224
        Where w2 = new Where(putRowValuesStock.getTable().getField("ID_ARTICLE"), "=", rowValsProduct.getID());
225
        Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
226
        if (rowValsResult.size() == 0) {
227
            SQLRowValues rowValsStock = new SQLRowValues(stockTable);
228
            rowValsStock.put("ID_ARTICLE", rowValsProduct.getID());
229
            rowValsStock.put("ID_DEPOT_STOCK", idDepot);
230
            rowValsStock.put("QTE_TH", 0F);
231
            rowValsStock.put("QTE_REEL", 0F);
232
            rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
233
            rowValsStock.put("QTE_LIV_ATTENTE", 0F);
234
            try {
235
                rowStock = rowValsStock.insert();
236
                if (idDepot == DepotStockSQLElement.DEFAULT_ID) {
237
                    rowValsProduct.createEmptyUpdateRow().put("ID_STOCK", rowStock.getID()).commit();
238
                }
239
            } catch (SQLException e) {
240
                ExceptionHandler.handle("Erreur lors la création du stock!", e);
241
            }
242
        } else if (rowValsResult.size() == 1) {
243
            rowStock = rowValsResult.iterator().next();
244
        } else if (rowValsResult.size() > 1) {
245
            throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + rowValsProduct.getID() + " Depot " + rowValsElt.getForeignID("ID_DEPOT_STOCK"));
246
        }
247
        return rowStock;
248
    }
174 ilm 249
 
250
    public static SQLRowAccessor findOrCreateStock(SQLRowAccessor article, SQLRowAccessor depot) {
251
 
252
        SQLRowAccessor rowStock = null;
253
        SQLTable stockTable = article.getTable().getTable("STOCK");
254
        SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
255
        putRowValuesStock.putNulls(stockTable.getTable().getFieldsName());
256
 
257
        SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
258
        Where w = new Where(putRowValuesStock.getTable().getField("ID_DEPOT_STOCK"), "=", depot.getID());
259
        Where w2 = new Where(putRowValuesStock.getTable().getField("ID_ARTICLE"), "=", article.getID());
260
        Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
261
        if (rowValsResult.size() == 0) {
262
            SQLRowValues rowValsStock = new SQLRowValues(stockTable);
263
            rowValsStock.put("ID_ARTICLE", article.getID());
264
            rowValsStock.put("ID_DEPOT_STOCK", depot.getID());
265
            rowValsStock.put("QTE_TH", 0F);
266
            rowValsStock.put("QTE_REEL", 0F);
267
            rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
268
            rowValsStock.put("QTE_LIV_ATTENTE", 0F);
269
            try {
270
                rowStock = rowValsStock.insert();
271
            } catch (SQLException e) {
272
                ExceptionHandler.handle("Erreur lors la création du stock!", e);
273
            }
274
        } else if (rowValsResult.size() == 1) {
275
            rowStock = rowValsResult.iterator().next();
276
        } else if (rowValsResult.size() > 1) {
277
            throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + article.getID() + " Depot " + depot.getID());
278
        }
279
        return rowStock;
280
 
281
    }
93 ilm 282
}