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
 
16
import org.openconcerto.sql.model.DBRoot;
17
import org.openconcerto.sql.model.SQLDataSource;
18
import org.openconcerto.sql.model.SQLRow;
19
import org.openconcerto.sql.model.SQLRowAccessor;
20
import org.openconcerto.sql.model.SQLRowListRSH;
21
import org.openconcerto.sql.model.SQLRowValues;
22
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
23
import org.openconcerto.sql.model.SQLSelect;
24
import org.openconcerto.sql.model.SQLTable;
25
import org.openconcerto.sql.model.Where;
26
import org.openconcerto.utils.DecimalUtils;
156 ilm 27
import org.openconcerto.utils.ListMap;
93 ilm 28
import org.openconcerto.utils.cc.ITransformer;
29
 
30
import java.math.BigDecimal;
132 ilm 31
import java.math.RoundingMode;
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.HashMap;
37
import java.util.HashSet;
38
import java.util.List;
39
import java.util.Map;
40
import java.util.Set;
41
 
42
public class ProductHelper {
43
 
44
    private DBRoot root;
45
 
46
    public ProductHelper(DBRoot root) {
47
        this.root = root;
48
    }
49
 
132 ilm 50
    public interface PriceField {
51
    };
52
 
53
    public enum SupplierPriceField implements PriceField {
54
        PRIX_ACHAT, COEF_TRANSPORT_PORT, COEF_TAXE_D, COEF_TRANSPORT_SIEGE, COEF_FRAIS_MOULE, COEF_FRAIS_INDIRECTS, COEF_PRIX_MINI
55
    };
56
 
57
    public BigDecimal getEnumPrice(final SQLRowAccessor r, PriceField field) {
58
        final PriceField[] values = field.getClass().getEnumConstants();
59
        BigDecimal result = r.getBigDecimal(values[0].toString());
60
        if (result == null) {
61
            return null;
62
        }
63
 
64
        for (int i = 1; i < values.length; i++) {
65
 
66
            BigDecimal m0 = r.getBigDecimal(values[i].toString());
67
            if (m0 != null && m0.floatValue() > 0) {
68
                result = result.divide(m0, 2, RoundingMode.HALF_UP);
69
            }
70
            if (values[i] == field) {
71
                break;
72
            }
73
        }
74
        return result;
75
    }
76
 
174 ilm 77
    /**
78
     * Fill productComponents with items (SQLrowAccessor of TABLE_ELEMENT)
79
     *
80
     * @param items
81
     * @param productComponents
82
     * @param qte
83
     * @param index
84
     * @param level
85
     */
86
    public void fillProductComponent(List<? extends SQLRowAccessor> itemsTableElement, List<ProductComponent> productComponents, int qte, int index, int level) {
87
        if (level > 0) {
88
            for (int i = index; i < itemsTableElement.size(); i++) {
89
                SQLRowAccessor r = itemsTableElement.get(i);
90
 
91
                if (!r.getTable().contains("NIVEAU") || r.getInt("NIVEAU") >= level) {
92
                    // On ne calcul pas les stocks pour les éléments ayant des fils (le mouvement de
93
                    // stock
94
                    // des fils impactera les stocks automatiquement)
95
                    if (r.getTable().contains("NIVEAU")) {
96
                        if (i + 1 < itemsTableElement.size()) {
97
                            SQLRowAccessor rNext = itemsTableElement.get(i + 1);
98
                            if (rNext.getInt("NIVEAU") > r.getInt("NIVEAU")) {
99
                                fillProductComponent(itemsTableElement, productComponents, qte * r.getInt("QTE"), i + 1, rNext.getInt("NIVEAU"));
100
                                continue;
101
                            }
102
                        }
103
                    }
104
                    if ((!r.getTable().contains("NIVEAU") || r.getInt("NIVEAU") == level) && r.getForeign("ID_ARTICLE") != null && !r.isForeignEmpty("ID_ARTICLE")) {
105
                        productComponents.add(ProductComponent.createFrom(r, qte, r));
106
                    }
107
                } else if (r.getInt("NIVEAU") < level) {
108
                    // BREAK si on sort de l'article composé
109
                    break;
110
                }
111
            }
112
        }
113
    }
114
 
93 ilm 115
    public BigDecimal getUnitCostForQuantity(SQLRowAccessor rArticle, int qty) {
116
 
117
        Collection<? extends SQLRowAccessor> l = rArticle.getReferentRows(rArticle.getTable().getTable("ARTICLE_PRIX_REVIENT"));
118
        BigDecimal result = null;
119
 
120
        for (SQLRowAccessor row : l) {
121
 
122
            if (row.getLong("QTE") > qty) {
123
                break;
124
            }
125
            result = row.getBigDecimal("PRIX");
126
        }
127
        if (result == null) {
128
            // Can occur during editing
129
            result = BigDecimal.ZERO;
130
        }
131
        return result;
132
    }
133
 
134
    @SuppressWarnings("unchecked")
135
    public List<String> getRequiredProperties(int categoryId) {
136
        final SQLTable table = root.getTable("FAMILLE_CARACTERISTIQUE");
137
        final SQLSelect sel = new SQLSelect();
138
        sel.addSelect(table.getField("NOM"));
139
        sel.setWhere(table.getField("ID_FAMILLE_ARTICLE"), "=", categoryId);
140
        final SQLDataSource src = root.getDBSystemRoot().getDataSource();
141
        return (List<String>) src.executeCol(sel.asString());
142
    }
143
 
144
    /**
145
     * Get the minimum quantity used to provide a cost for a product
146
     *
147
     * @return -1 if no quantity are provided
132 ilm 148
     */
93 ilm 149
    public int getMinQuantityForCostCalculation(int productId) {
150
        final SQLTable costTable = root.getTable("ARTICLE_PRIX_REVIENT");
151
        final SQLSelect sel = new SQLSelect();
152
        sel.addSelect(costTable.getKey());
153
        sel.addSelect(costTable.getField("ID_ARTICLE"));
154
        sel.addSelect(costTable.getField("QTE"));
155
        sel.setWhere(new Where(costTable.getField("ID_ARTICLE"), "=", productId));
156
        final SQLDataSource src = root.getDBSystemRoot().getDataSource();
157
        final List<SQLRow> l = (List<SQLRow>) src.execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
158
        if (l.isEmpty()) {
159
            return -1;
160
        }
161
        int min = Integer.MAX_VALUE;
162
        for (SQLRow sqlRow : l) {
163
            int n = sqlRow.getInt("QTE");
164
            if (n < min) {
165
                min = n;
166
            }
167
        }
168
        return min;
169
    }
170
 
171
    /**
172
     * Get the cost for products and quantities
173
     *
174
     * @return for each product ID the unit cost
132 ilm 175
     */
93 ilm 176
    public Map<Long, BigDecimal> getUnitCost(Map<Long, Integer> productQties, TypePrice type) {
177
        final Map<Long, BigDecimal> result = new HashMap<Long, BigDecimal>();
132 ilm 178
 
142 ilm 179
        String fieldPrice = (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR || type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP ? "PRIX_ACHAT_DEVISE_F" : "PRIX");
180
        String fieldDate = (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR || type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP ? "DATE_PRIX" : "DATE");
132 ilm 181
 
93 ilm 182
        // get all costs
142 ilm 183
        final SQLTable costTable = root.getTable(type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP ? "ARTICLE_TARIF_FOURNISSEUR" : type.name());
93 ilm 184
        final SQLSelect sel = new SQLSelect();
185
        sel.addSelect(costTable.getKey());
186
        sel.addSelect(costTable.getField("ID_ARTICLE"));
187
        sel.addSelect(costTable.getField("QTE"));
132 ilm 188
        sel.addSelect(costTable.getField(fieldPrice));
142 ilm 189
        if (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP) {
190
            for (SupplierPriceField f : SupplierPriceField.values()) {
191
                sel.addSelect(costTable.getField(f.name()));
192
            }
193
        }
132 ilm 194
        sel.addSelect(costTable.getField(fieldDate));
93 ilm 195
        sel.setWhere(new Where(costTable.getField("ID_ARTICLE"), true, productQties.keySet()));
196
        sel.addFieldOrder(costTable.getField("QTE"));
132 ilm 197
        sel.addFieldOrder(costTable.getField(fieldDate));
93 ilm 198
        final SQLDataSource src = root.getDBSystemRoot().getDataSource();
199
        @SuppressWarnings("unchecked")
200
        final List<SQLRow> l = (List<SQLRow>) src.execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
201
        for (SQLRow sqlRow : l) {
202
            System.out.println(sqlRow.getID() + ":" + sqlRow.getAllValues());
203
        }
204
        final int size = l.size();
142 ilm 205
        if (size == 0 && type == TypePrice.ARTICLE_PRIX_REVIENT) {
206
            return getUnitCost(productQties, TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP);
207
        } else {
208
            for (Long id : productQties.keySet()) {
209
                BigDecimal cost = BigDecimal.ZERO;
210
                final int qty = productQties.get(id);
211
                for (int i = 0; i < size; i++) {
212
                    final SQLRow row = l.get(i);
213
                    if (row.getInt("ID_ARTICLE") == id.intValue()) {
214
                        // stop when the max qty is found
215
                        if (row.getLong("QTE") > qty) {
216
                            if (cost == null) {
217
                                if (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP) {
218
                                    cost = getEnumPrice(row, SupplierPriceField.COEF_TRANSPORT_SIEGE);
219
                                } else {
220
                                    cost = row.getBigDecimal(fieldPrice);
221
                                }
222
                            }
223
                            break;
224
                        }
225
                        if (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR_DDP) {
226
                            cost = getEnumPrice(row, SupplierPriceField.COEF_TRANSPORT_SIEGE);
227
                        } else {
132 ilm 228
                            cost = row.getBigDecimal(fieldPrice);
93 ilm 229
                        }
142 ilm 230
 
93 ilm 231
                    }
142 ilm 232
                }
233
                if (cost == null) {
234
                    cost = BigDecimal.ZERO;
235
                }
93 ilm 236
 
142 ilm 237
                result.put(id, cost);
93 ilm 238
            }
142 ilm 239
            return result;
93 ilm 240
        }
241
    }
242
 
243
    /**
244
     *
245
     * @param items List de SQLRowAccessor avec ID_ARTICLE, QTE, QTE_UV
246
     * @return Map article qty
247
     */
248
    public List<ProductComponent> getChildWithQtyFrom(final List<ProductComponent> items) {
249
 
250
        return getChildWithQtyFrom(items, new HashSet<Integer>());
251
    }
252
 
156 ilm 253
    private List<ProductComponent> getChildWithQtyFrom(List<ProductComponent> items, Set<Integer> ancestorsOrigin) {
93 ilm 254
 
255
        if (root.contains("ARTICLE_ELEMENT")) {
256
 
156 ilm 257
            int originalAncestorsSize = ancestorsOrigin.size();
258
            Set<Integer> ancestors = new HashSet<Integer>(ancestorsOrigin);
93 ilm 259
 
260
            List<ProductComponent> result = new ArrayList<ProductComponent>();
261
 
262
            // liste des ids parents
263
            final List<Integer> parentsArticleIDs = new ArrayList<Integer>();
264
 
156 ilm 265
            // ID Article -- component
266
            ListMap<Integer, ProductComponent> productCompByID = new ListMap<Integer, ProductComponent>();
267
 
93 ilm 268
            // Quantité par parents
156 ilm 269
            // final ListMap<Integer, BigDecimal> qtyParentIDSource = new HashMap<Integer,
270
            // BigDecimal>();
93 ilm 271
            for (ProductComponent p : items) {
156 ilm 272
                productCompByID.add(p.getProduct().getID(), p);
273
                int idSource = p.getProduct().getID();
274
                parentsArticleIDs.add(idSource);
275
                // BigDecimal qty = BigDecimal.ZERO;
276
                // if (qtyParent.get(idSource) != null) {
277
                // qty = qtyParent.get(idSource);
278
                // }
279
                // qtyParent.put(idSource, qty.add(p.getQty()));
93 ilm 280
            }
281
 
282
            // get all childs
283
            final SQLTable costTable = root.getTable("ARTICLE_ELEMENT");
284
 
285
            SQLRowValues rowVals = new SQLRowValues(costTable);
286
 
174 ilm 287
            final SQLRowValues artRowValues = rowVals.putRowValues("ID_ARTICLE").putNulls("ID", "GESTION_STOCK", "CODE", "NOM", "ID_DEPOT_STOCK", "ID_UNITE_VENTE", "ID_FOURNISSEUR");
156 ilm 288
            SQLRowValues stockRowVals = new SQLRowValues(root.getTable("STOCK"));
289
            stockRowVals.putNulls("QTE_TH", "QTE_RECEPT_ATTENTE", "QTE_REEL", "QTE_LIV_ATTENTE", "ID_DEPOT_STOCK");
290
            stockRowVals.put("ID_ARTICLE", artRowValues);
93 ilm 291
            rowVals.putRowValues("ID_ARTICLE_PARENT").put("ID", null);
292
            rowVals.put("QTE", null);
293
            rowVals.put("QTE_UNITAIRE", null);
294
 
295
            SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowVals);
296
            fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
297
 
298
                @Override
299
                public SQLSelect transformChecked(SQLSelect input) {
300
 
301
                    input.setWhere(new Where(costTable.getField("ID_ARTICLE_PARENT"), parentsArticleIDs));
302
                    return input;
303
                }
304
            });
305
 
306
            List<SQLRowValues> childs = fetcher.fetch();
307
 
308
            if (childs.size() > 0) {
309
 
310
                for (SQLRowValues childRowValues : childs) {
311
                    final SQLRowAccessor foreignArticleParent = childRowValues.getForeign("ID_ARTICLE_PARENT");
312
 
156 ilm 313
                    if (childRowValues.getObject("ID_ARTICLE") != null && !childRowValues.isForeignEmpty("ID_ARTICLE")) {
314
 
315
                        List<ProductComponent> source = productCompByID.get(foreignArticleParent.getID());
142 ilm 316
                        // Test pour éviter les boucles dans les boms
156 ilm 317
                        if (!ancestorsOrigin.contains(foreignArticleParent.getID())) {
142 ilm 318
                            ancestors.add(foreignArticleParent.getID());
156 ilm 319
                            for (ProductComponent productParent : source) {
142 ilm 320
 
156 ilm 321
                                final SQLRowAccessor foreignArticle = childRowValues.getForeign("ID_ARTICLE");
322
                                ProductComponent childComponent = ProductComponent.createFromRowArticle(foreignArticle, productParent.getSource());
323
 
324
                                // parentsArticleIDs.remove(foreignArticleParent.getID());
325
                                // Calcul de la quantité qte_unit * qte * qteMergedParent
326
                                childComponent.setQty(childComponent.getQty().multiply(productParent.getQty(), DecimalUtils.HIGH_PRECISION));
327
 
328
                                // Cumul des valeurs si l'article est présent plusieurs fois dans le
329
                                // bom
330
                                // ProductComponent existProduct =
331
                                // productCompByID.get(childComponent.getProduct().getID());
332
                                // if (existProduct == null) {
333
                                // Maintenant on garde une ligne disctincte pour chaque kit
142 ilm 334
                                result.add(childComponent);
156 ilm 335
                                // productCompByID.put(childComponent.getProduct().getID(),
336
                                // childComponent);
337
                                // } else {
338
                                // existProduct.addQty(childComponent.getQty());
339
                                // }
142 ilm 340
                            }
93 ilm 341
                        }
342
                    }
343
                }
344
 
345
                // Recherche si un kit est présent parmis les articles
346
                final List<ProductComponent> bomFromChilds = getChildWithQtyFrom(new ArrayList(result), ancestors);
347
                // Merge des valeurs
348
                for (ProductComponent s : bomFromChilds) {
349
 
156 ilm 350
                    // ProductComponent existProduct = productCompByID.get(s.getProduct().getID());
351
                    // if (existProduct == null) {
352
                    result.add(s);
353
                    // productCompByID.put(s.getProduct().getID(), s);
354
                    // } else {
355
                    // existProduct.addQty(s.getQty());
356
                    // }
93 ilm 357
                }
358
            }
359
 
360
            // Ajout des articles présents dans l'ensemble de départ
361
            if (originalAncestorsSize == 0) {
362
                for (ProductComponent p : items) {
156 ilm 363
                    // ProductComponent existProduct = productCompByID.get(p.getProduct().getID());
364
                    // if (existProduct == null) {
365
                    result.add(p);
366
                    // productCompByID.put(p.getProduct().getID(), p);
367
                    // } else {
368
                    // existProduct.addQty(p.getQty());
369
                    // }
93 ilm 370
                }
371
            }
372
 
373
            // On supprime les ancestors (kits) du result
374
            for (Integer anc : ancestors) {
156 ilm 375
                // ProductComponent comp = productCompByID.get(anc);
376
                if (productCompByID.containsKey(anc)) {
377
                    result.removeAll(productCompByID.get(anc));
93 ilm 378
                }
379
            }
380
 
381
            return result;
382
        } else {
383
            return items;
384
        }
385
    }
386
 
387
    public Map<Long, Integer> getBOM(Long productId) {
388
        final Map<Long, Integer> result = new HashMap<Long, Integer>();
389
        // get all costs
390
        final SQLTable costTable = root.getTable("ARTICLE_ELEMENT");
391
        final SQLSelect sel = new SQLSelect();
392
 
393
        sel.addSelect(costTable.getField("ID_ARTICLE"));
394
        sel.addSelect(costTable.getField("QTE"));
395
 
396
        sel.setWhere(new Where(costTable.getField("ID_ARTICLE_PARENT"), "=", productId));
397
        sel.addFieldOrder(costTable.getField("QTE"));
398
        final SQLDataSource src = root.getDBSystemRoot().getDataSource();
399
        @SuppressWarnings("unchecked")
400
        final List<SQLRow> l = (List<SQLRow>) src.execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
401
        final int size = l.size();
402
        for (int i = 0; i < size; i++) {
403
            final SQLRow row = l.get(i);
404
            final long id = row.getLong("ID_ARTICLE");
405
            Integer qte = result.get(id);
406
            if (qte == null) {
407
                qte = row.getInt("QTE");
408
            } else {
409
                qte = qte + row.getInt("QTE");
410
            }
411
            result.put(id, qte);
412
        }
413
 
414
        return result;
415
    }
416
 
417
    public enum TypePrice {
142 ilm 418
        ARTICLE_PRIX_REVIENT, ARTICLE_PRIX_MIN_VENTE, ARTICLE_PRIX_PUBLIC, ARTICLE_TARIF_FOURNISSEUR, ARTICLE_TARIF_FOURNISSEUR_DDP
93 ilm 419
    };
420
 
421
    public BigDecimal getBomPriceForQuantity(int qty, Collection<? extends SQLRowAccessor> rowValuesProductItems, TypePrice type) {
422
        final Map<Long, Integer> productQties = new HashMap<Long, Integer>();
423
        int count = rowValuesProductItems.size();
424
        for (SQLRowAccessor v : rowValuesProductItems) {
425
            if (v.getObject("ID_ARTICLE") != null) {
426
                System.out.println("id:" + v.getObject("ID_ARTICLE"));
427
                int id = v.getForeignID("ID_ARTICLE");
428
                int qte = v.getInt("QTE") * qty;
429
                Integer qteForId = productQties.get(Long.valueOf(id));
430
                if (qteForId == null) {
431
                    productQties.put(Long.valueOf(id), qte);
432
                } else {
433
                    productQties.put(Long.valueOf(id), qte + qteForId);
434
                }
435
            }
436
        }
437
        Map<Long, BigDecimal> costs = getUnitCost(productQties, type);
438
        BigDecimal cost = null;
439
        for (SQLRowAccessor v : rowValuesProductItems) {
440
            if (v.getObject("ID_ARTICLE") != null) {
441
                int id = v.getForeignID("ID_ARTICLE");
442
                int qte = v.getInt("QTE");
443
                final BigDecimal unitCost = costs.get(Long.valueOf(id));
94 ilm 444
                BigDecimal lineCost = unitCost.multiply(BigDecimal.valueOf(qte)).multiply(v.getBigDecimal("QTE_UNITAIRE"));
93 ilm 445
                if (cost == null) {
446
                    cost = BigDecimal.ZERO;
447
                }
448
                cost = cost.add(lineCost);
449
            }
450
        }
451
        return cost;
452
 
453
    }
454
 
455
    public BigDecimal getUnitCost(int id, int qty, TypePrice type) {
456
        Map<Long, Integer> productQties = new HashMap<Long, Integer>();
457
        productQties.put(Long.valueOf(id), Integer.valueOf(qty));
458
        final Map<Long, BigDecimal> unitCost = getUnitCost(productQties, type);
459
        System.out.println(">" + unitCost);
460
        return unitCost.get(Long.valueOf(id));
461
    }
462
 
463
    public Date getUnitCostDate(int id, int qty, TypePrice type) {
464
        Map<Long, Integer> productQties = new HashMap<Long, Integer>();
465
        productQties.put(Long.valueOf(id), Integer.valueOf(qty));
466
        final Map<Long, Date> unitCost = getUnitCostDate(productQties, type);
467
        System.out.println(">" + unitCost);
468
        return unitCost.get(Long.valueOf(id));
469
    }
470
 
471
    private Map<Long, Date> getUnitCostDate(Map<Long, Integer> productQties, TypePrice type) {
472
        final Map<Long, Date> result = new HashMap<Long, Date>();
132 ilm 473
 
474
        String fieldPrice = (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR ? "PRIX_ACHAT_DEVISE_F" : "PRIX");
475
        String fieldDate = (type == TypePrice.ARTICLE_TARIF_FOURNISSEUR ? "DATE_PRIX" : "DATE");
476
 
93 ilm 477
        // get all costs
478
        final SQLTable costTable = root.getTable(type.name());
479
        final SQLSelect sel = new SQLSelect();
480
        sel.addSelect(costTable.getKey());
481
        sel.addSelect(costTable.getField("ID_ARTICLE"));
482
        sel.addSelect(costTable.getField("QTE"));
132 ilm 483
        sel.addSelect(costTable.getField(fieldPrice));
484
        sel.addSelect(costTable.getField(fieldDate));
93 ilm 485
        sel.setWhere(new Where(costTable.getField("ID_ARTICLE"), true, productQties.keySet()));
486
        sel.addFieldOrder(costTable.getField("QTE"));
132 ilm 487
        sel.addFieldOrder(costTable.getField(fieldDate));
93 ilm 488
        final SQLDataSource src = root.getDBSystemRoot().getDataSource();
489
        @SuppressWarnings("unchecked")
490
        final List<SQLRow> l = (List<SQLRow>) src.execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
491
        for (SQLRow sqlRow : l) {
492
            System.out.println(sqlRow.getID() + ":" + sqlRow.getAllValues());
493
        }
494
        final int size = l.size();
495
        for (Long id : productQties.keySet()) {
496
            Calendar cost = null;
497
            final int qty = productQties.get(id);
498
            for (int i = 0; i < size; i++) {
499
                final SQLRow row = l.get(i);
500
                if (row.getInt("ID_ARTICLE") == id.intValue()) {
501
                    // stop when the max qty is found
502
                    if (row.getLong("QTE") > qty) {
503
                        if (cost == null) {
504
                            cost = row.getDate("DATE");
505
                        }
506
                        break;
507
                    }
508
                    cost = row.getDate("DATE");
509
 
510
                }
511
            }
512
            if (cost != null)
513
                result.put(id, cost.getTime());
514
            else
515
                result.put(id, new Date());
516
        }
517
        return result;
518
    }
519
}