OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 174 | 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
 
180 ilm 137
    public static ProductComponent createFromRowArticle(SQLRowAccessor rowArticle, BigDecimal qty, SQLRowAccessor rowValsSource) {
156 ilm 138
        SQLRowAccessor rowStock = getStock(rowArticle, rowArticle, rowValsSource);
139
 
180 ilm 140
        return new ProductComponent(rowArticle, qty, rowValsSource, rowStock);
156 ilm 141
    }
142
 
180 ilm 143
    public static ProductComponent createFromRowArticle(SQLRowAccessor rowArticle, SQLRowAccessor rowValsSource) {
144
        return createFromRowArticle(rowArticle, BigDecimal.ONE, rowValsSource);
145
    }
146
 
93 ilm 147
    public static ProductComponent createFrom(SQLRowAccessor rowVals) {
156 ilm 148
        return createFrom(rowVals, 1, rowVals);
93 ilm 149
    }
150
 
156 ilm 151
    public static ProductComponent createFrom(SQLRowAccessor rowVals, SQLRowAccessor rowValsSource) {
152
        return createFrom(rowVals, 1, rowValsSource);
153
    }
93 ilm 154
 
156 ilm 155
    public static ProductComponent createFrom(SQLRowAccessor rowVals, int qteMultiple, SQLRowAccessor rowValsSource) {
156
 
157
        if (rowVals.getForeign("ID_ARTICLE") == null || rowVals.isForeignEmpty("ID_ARTICLE")) {
158
            throw new IllegalArgumentException("Aucun article associé à la row " + rowVals.getTable().getName() + " " + rowVals.getID());
159
        }
132 ilm 160
        final int qteMult = (rowVals.getTable().getName().equalsIgnoreCase("BON_DE_LIVRAISON_ELEMENT") ? rowVals.getInt("QTE_LIVREE") : rowVals.getInt("QTE"));
161
        final int qte = qteMult * qteMultiple;
93 ilm 162
        final BigDecimal qteUV = rowVals.getBigDecimal("QTE_UNITAIRE");
163
        BigDecimal qteFinal = qteUV.multiply(new BigDecimal(qte), DecimalUtils.HIGH_PRECISION);
156 ilm 164
        SQLRowAccessor rowStock = getStock(rowVals.getForeign("ID_ARTICLE"), rowVals, rowValsSource);
165
 
166
        // }
167
        // else {
168
        // rowStock = rowVals.getForeign("ID_ARTICLE").getForeign("ID_STOCK");
169
        // }
170
        return new ProductComponent(rowVals.getForeign("ID_ARTICLE"), qteFinal, rowValsSource, rowStock);
171
        // return new ProductComponent(rowVals.getForeign("ID_ARTICLE"), qteFinal);
93 ilm 172
    }
156 ilm 173
 
174
    private static SQLRowAccessor getStock(SQLRowAccessor rowValsProduct, SQLRowAccessor rowValsElt, SQLRowAccessor rowValsSource) {
175
        SQLRowAccessor rowStock = null;
174 ilm 176
        int idDepot = -1;
177
 
178
        if (rowValsProduct.getTable().getDBRoot().contains("AFFAIRE")) {
179
            SQLTable tableAff = rowValsProduct.getTable().getTable("AFFAIRE");
180
            if (tableAff.contains("ID_DEPOT_STOCK")) {
181
                if (rowValsSource.getFields().contains("ID_DEPOT_STOCK") && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
182
                    idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
183
                } else if (rowValsSource.getFields().contains("ID_AFFAIRE") && !rowValsSource.isForeignEmpty("ID_AFFAIRE")) {
184
                    SQLRowAccessor rowAff = rowValsSource.getForeign("ID_AFFAIRE");
185
                    if (rowAff.getFields().contains("ID_DEPOT_STOCK") && !rowAff.isForeignEmpty("ID_DEPOT_STOCK")) {
186
                        idDepot = rowAff.getForeignID("ID_DEPOT_STOCK");
187
                    }
188
                } else {
189
                    SQLField fieldParent = Configuration.getInstance().getDirectory().getElement(rowValsSource.getTable()).getParentForeignField();
190
                    if (fieldParent != null) {
191
                        SQLRowAccessor parent = rowValsSource.getForeign(fieldParent.getName());
192
 
193
                        if (parent.getFields().contains("ID_AFFAIRE") && !parent.isForeignEmpty("ID_AFFAIRE")) {
194
                            SQLRowAccessor rowAff = parent.getForeign("ID_AFFAIRE");
195
                            if (rowAff.getFields().contains("ID_DEPOT_STOCK") && !rowAff.isForeignEmpty("ID_DEPOT_STOCK")) {
196
                                idDepot = rowAff.getForeignID("ID_DEPOT_STOCK");
197
                            }
198
                        }
199
                    }
200
                }
201
            }
202
        }
203
 
204
        if (idDepot == -1) {
205
 
206
            if (rowValsSource.getFields().contains("ID_DEPOT_STOCK") && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
207
                idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
156 ilm 208
            } else {
174 ilm 209
                if (rowValsElt.getForeign("ID_DEPOT_STOCK") != null && !rowValsElt.isForeignEmpty("ID_DEPOT_STOCK")) {
210
                    idDepot = rowValsElt.getForeignID("ID_DEPOT_STOCK");
211
                } else {
212
                    idDepot = DepotStockSQLElement.DEFAULT_ID;
213
                    try {
214
                        rowValsElt.createEmptyUpdateRow().put("ID_DEPOT_STOCK", idDepot).commit();
215
                    } catch (SQLException e) {
216
                        ExceptionHandler.handle("Erreur lors de l'initialisation du stock!", e);
217
                    }
218
 
156 ilm 219
                }
220
            }
221
        }
222
        SQLTable stockTable = rowValsElt.getTable().getTable("STOCK");
223
        SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
224
        putRowValuesStock.putNulls(stockTable.getTable().getFieldsName());
225
 
226
        SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
227
        Where w = new Where(putRowValuesStock.getTable().getField("ID_DEPOT_STOCK"), "=", idDepot);
228
        Where w2 = new Where(putRowValuesStock.getTable().getField("ID_ARTICLE"), "=", rowValsProduct.getID());
229
        Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
230
        if (rowValsResult.size() == 0) {
231
            SQLRowValues rowValsStock = new SQLRowValues(stockTable);
232
            rowValsStock.put("ID_ARTICLE", rowValsProduct.getID());
233
            rowValsStock.put("ID_DEPOT_STOCK", idDepot);
234
            rowValsStock.put("QTE_TH", 0F);
235
            rowValsStock.put("QTE_REEL", 0F);
236
            rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
237
            rowValsStock.put("QTE_LIV_ATTENTE", 0F);
238
            try {
239
                rowStock = rowValsStock.insert();
240
                if (idDepot == DepotStockSQLElement.DEFAULT_ID) {
241
                    rowValsProduct.createEmptyUpdateRow().put("ID_STOCK", rowStock.getID()).commit();
242
                }
243
            } catch (SQLException e) {
244
                ExceptionHandler.handle("Erreur lors la création du stock!", e);
245
            }
246
        } else if (rowValsResult.size() == 1) {
247
            rowStock = rowValsResult.iterator().next();
248
        } else if (rowValsResult.size() > 1) {
249
            throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + rowValsProduct.getID() + " Depot " + rowValsElt.getForeignID("ID_DEPOT_STOCK"));
250
        }
251
        return rowStock;
252
    }
174 ilm 253
 
254
    public static SQLRowAccessor findOrCreateStock(SQLRowAccessor article, SQLRowAccessor depot) {
255
 
256
        SQLRowAccessor rowStock = null;
257
        SQLTable stockTable = article.getTable().getTable("STOCK");
258
        SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
259
        putRowValuesStock.putNulls(stockTable.getTable().getFieldsName());
260
 
261
        SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
262
        Where w = new Where(putRowValuesStock.getTable().getField("ID_DEPOT_STOCK"), "=", depot.getID());
263
        Where w2 = new Where(putRowValuesStock.getTable().getField("ID_ARTICLE"), "=", article.getID());
264
        Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
265
        if (rowValsResult.size() == 0) {
266
            SQLRowValues rowValsStock = new SQLRowValues(stockTable);
267
            rowValsStock.put("ID_ARTICLE", article.getID());
268
            rowValsStock.put("ID_DEPOT_STOCK", depot.getID());
269
            rowValsStock.put("QTE_TH", 0F);
270
            rowValsStock.put("QTE_REEL", 0F);
271
            rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
272
            rowValsStock.put("QTE_LIV_ATTENTE", 0F);
273
            try {
274
                rowStock = rowValsStock.insert();
275
            } catch (SQLException e) {
276
                ExceptionHandler.handle("Erreur lors la création du stock!", e);
277
            }
278
        } else if (rowValsResult.size() == 1) {
279
            rowStock = rowValsResult.iterator().next();
280
        } else if (rowValsResult.size() > 1) {
281
            throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + article.getID() + " Depot " + depot.getID());
282
        }
283
        return rowStock;
284
 
285
    }
93 ilm 286
}