OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 149 | Rev 156 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
132 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.pos;
15
 
144 ilm 16
import org.openconcerto.erp.action.NouvelleConnexionAction;
132 ilm 17
import org.openconcerto.erp.config.ComptaPropsConfiguration;
18
import org.openconcerto.erp.config.MainFrame;
19
import org.openconcerto.erp.core.common.ui.TotalCalculator;
20
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
21
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
22
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
23
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
149 ilm 24
import org.openconcerto.erp.core.sales.pos.io.Printable;
132 ilm 25
import org.openconcerto.erp.core.sales.pos.io.TicketPrinter;
26
import org.openconcerto.erp.core.sales.pos.model.Article;
142 ilm 27
import org.openconcerto.erp.core.sales.pos.model.Client;
132 ilm 28
import org.openconcerto.erp.core.sales.pos.model.Paiement;
29
import org.openconcerto.erp.core.sales.pos.model.ReceiptCode;
144 ilm 30
import org.openconcerto.erp.core.sales.pos.model.RegisterFiles.HashMode;
31
import org.openconcerto.erp.core.sales.pos.model.RegisterLogEntry.ReceiptEntry;
132 ilm 32
import org.openconcerto.erp.core.sales.pos.model.Ticket;
33
import org.openconcerto.erp.core.sales.pos.model.TicketLine;
34
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater;
35
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater.TypeStockUpdate;
36
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
37
import org.openconcerto.erp.generationEcritures.GenerationMvtTicketCaisse;
38
import org.openconcerto.erp.generationEcritures.GenerationMvtVirement;
39
import org.openconcerto.erp.generationEcritures.GenerationReglementVenteNG;
40
import org.openconcerto.erp.model.PrixTTC;
41
import org.openconcerto.erp.preferences.DefaultNXProps;
42
import org.openconcerto.sql.Configuration;
43
import org.openconcerto.sql.element.SQLElement;
44
import org.openconcerto.sql.model.SQLBase;
144 ilm 45
import org.openconcerto.sql.model.SQLDataSource;
132 ilm 46
import org.openconcerto.sql.model.SQLRow;
47
import org.openconcerto.sql.model.SQLRowAccessor;
48
import org.openconcerto.sql.model.SQLRowValues;
142 ilm 49
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
132 ilm 50
import org.openconcerto.sql.model.SQLSelect;
51
import org.openconcerto.sql.model.SQLSelectHandlerBuilder;
52
import org.openconcerto.sql.model.SQLTable;
53
import org.openconcerto.sql.model.Where;
54
import org.openconcerto.sql.utils.SQLUtils;
142 ilm 55
import org.openconcerto.utils.BaseDirs;
132 ilm 56
import org.openconcerto.utils.DecimalUtils;
57
import org.openconcerto.utils.ExceptionHandler;
58
import org.openconcerto.utils.Pair;
59
import org.openconcerto.utils.i18n.TranslationManager;
60
 
61
import java.io.File;
62
import java.io.FileOutputStream;
63
import java.io.IOException;
64
import java.math.BigDecimal;
65
import java.math.RoundingMode;
144 ilm 66
import java.nio.file.Path;
132 ilm 67
import java.sql.SQLException;
68
import java.util.ArrayList;
142 ilm 69
import java.util.Collections;
70
import java.util.Comparator;
132 ilm 71
import java.util.Date;
144 ilm 72
import java.util.Iterator;
132 ilm 73
import java.util.List;
74
import java.util.Locale;
144 ilm 75
import java.util.logging.Logger;
132 ilm 76
 
77
import javax.swing.JOptionPane;
78
import javax.swing.SwingUtilities;
79
 
80
import org.jdom2.Document;
81
import org.jdom2.Element;
82
import org.jdom2.input.SAXBuilder;
83
import org.jdom2.output.Format;
84
import org.jdom2.output.XMLOutputter;
85
 
86
public class POSConfiguration {
144 ilm 87
 
88
    private static final Logger LOG = Logger.getLogger(org.openconcerto.erp.config.Log.get().getName() + ".pos");
89
 
90
    public static final Logger getLogger() {
91
        return LOG;
92
    }
93
 
94
    public static final void checkRegisterID(final int fsID, final int dbID) {
95
        if (fsID != dbID)
96
            throw new IllegalArgumentException("Not same register, FS " + fsID + ", DB " + dbID);
97
    }
98
 
132 ilm 99
    private static final String POS_CONFIGURATION_FILENAME = "pos.xml";
100
    private static POSConfiguration instance;
142 ilm 101
 
102
    private final File confFile;
132 ilm 103
    private int screenWidth, screenHeight;
104
    private TicketPrinterConfiguration ticketPrinterConf1, ticketPrinterConf2;
105
    private int userID = 2;
106
    private int companyID = 42;
107
    private int posID = 2;
108
    private int scanDelay = 80;
109
 
110
    private List<TicketLine> headerLines = new ArrayList<TicketLine>();
111
    private List<TicketLine> footerLines = new ArrayList<TicketLine>();
112
    // Terminal CB
113
    private String creditCardPort = "";
114
    // LCD
142 ilm 115
    private String LCDType = "serial";
116
    private String LCDPort = "";
132 ilm 117
    private String LCDLine1 = "Bienvenue";
118
    private String LCDLine2 = "ILM Informatique";
119
 
120
    public static synchronized POSConfiguration getInstance() {
121
        if (instance == null) {
142 ilm 122
            instance = new POSConfiguration(getConfigFile(new File(".")));
132 ilm 123
            instance.loadConfiguration();
124
        }
125
        return instance;
126
    }
127
 
142 ilm 128
    private POSConfiguration(final File confFile) {
129
        this.confFile = confFile;
132 ilm 130
        ticketPrinterConf1 = new TicketPrinterConfiguration();
131
        ticketPrinterConf2 = new TicketPrinterConfiguration();
132
        // Desactivate second printer by default
133
        ticketPrinterConf2.setCopyCount(0);
134
    }
135
 
136
    public TicketPrinterConfiguration getTicketPrinterConfiguration1() {
137
        return ticketPrinterConf1;
138
    }
139
 
140
    public TicketPrinterConfiguration getTicketPrinterConfiguration2() {
141
        return ticketPrinterConf2;
142
    }
143
 
144
    public boolean isConfigurationFileCreated() {
145
        File file = getConfigFile();
146
        if (file == null) {
147
            return false;
148
        }
149
        return file.exists();
150
    }
151
 
152
    // Screen
153
    public int getScreenWidth() {
154
        return screenWidth;
155
    }
156
 
157
    public int getScreenHeight() {
158
        return screenHeight;
159
    }
160
 
161
    // Database connection
162
    public int getUserID() {
163
        return userID;
164
    }
165
 
166
    public void setUserID(int userID) {
167
        this.userID = userID;
168
    }
169
 
170
    public int getCompanyID() {
171
        return companyID;
172
    }
173
 
174
    public void setCompanyID(int companyID) {
175
        this.companyID = companyID;
176
    }
177
 
178
    // POS id
179
    public int getPosID() {
180
        return posID;
181
    }
182
 
183
    public void setPosID(int posID) {
184
        this.posID = posID;
185
    }
186
 
187
    public int getScanDelay() {
188
        return scanDelay;
189
    }
190
 
191
    /**
192
     * Set barcode scanner delay
193
     */
194
    public void setScanDelay(int ms) {
195
        this.scanDelay = ms;
196
    }
197
 
198
    public String getCreditCardPort() {
199
        return creditCardPort;
200
    }
201
 
202
    /**
203
     * Set the serial port of the credit card device
204
     */
205
    public void setCreditCardPort(String creditCardPort) {
206
        this.creditCardPort = creditCardPort;
207
    }
208
 
142 ilm 209
    private static File getConfigFile(final File wd) {
132 ilm 210
        final File wdFile = new File(wd + "/Configuration", POS_CONFIGURATION_FILENAME);
211
        final File confFile;
212
        if (wdFile.isFile()) {
213
            confFile = wdFile;
214
        } else {
142 ilm 215
            try {
216
                final File preferencesFolder = BaseDirs.create(ComptaPropsConfiguration.productInfo).getPreferencesFolderToWrite();
217
                confFile = new File(preferencesFolder, POS_CONFIGURATION_FILENAME);
218
            } catch (IOException e) {
219
                throw new IllegalStateException("Couldn't get folder", e);
132 ilm 220
            }
221
        }
222
        return confFile;
223
    }
224
 
142 ilm 225
    public final File getConfigFile() {
226
        return this.confFile;
132 ilm 227
    }
228
 
144 ilm 229
    public ComptaPropsConfiguration createConnexion() {
132 ilm 230
        final ComptaPropsConfiguration conf = ComptaPropsConfiguration.create();
231
        TranslationManager.getInstance().addTranslationStreamFromClass(MainFrame.class);
232
        TranslationManager.getInstance().setLocale(Locale.getDefault());
233
 
234
        Configuration.setInstance(conf);
235
        try {
144 ilm 236
            conf.getUserManager().setCurrentUserID(getUserID());
237
            conf.setUpSocieteDataBaseConnexion(getCompanyID());
132 ilm 238
        } catch (Exception e) {
144 ilm 239
            JOptionPane.showMessageDialog(null, "Impossible de configurer la connexion à la base de donnée.\n ID société: " + getCompanyID() + " \n ID utilisateur: " + getUserID());
132 ilm 240
            e.printStackTrace();
144 ilm 241
            System.exit(2);
132 ilm 242
        }
243
 
144 ilm 244
        NouvelleConnexionAction.initCache(conf);
245
 
246
        return conf;
132 ilm 247
    }
248
 
144 ilm 249
    public final Path getRootDir() throws IOException {
250
        return Configuration.getInstance().getBaseDirs().getAppDataFolderToWrite().toPath();
251
    }
252
 
253
    public final void closeConnexion() {
254
        Configuration.setInstance(null, true);
255
    }
256
 
132 ilm 257
    public void commitAll(final List<Ticket> tickets) {
258
        // createConnexion();
259
        try {
260
            SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLUtils.SQLFactory<Object>() {
261
                @Override
262
                public Object create() throws SQLException {
151 ilm 263
 
144 ilm 264
                    final int imported = importReceipts(tickets, null);
132 ilm 265
 
266
                    // mark imported
267
                    for (Ticket ticket : tickets) {
268
                        final ReceiptCode code = ticket.getReceiptCode();
269
                        try {
270
                            // it's OK if some files cannot be moved, the next call will try again
271
                            // (the above code doesn't import duplicates)
272
                            code.markImported();
273
                        } catch (IOException e) {
274
                            e.printStackTrace();
275
                        }
276
                    }
277
                    // archive to avoid parsing more and more receipts
278
                    try {
279
                        // it's OK if some files cannot be moved, the next call will try again
280
                        ReceiptCode.archiveCompletelyImported();
281
                    } catch (IOException e) {
282
                        e.printStackTrace();
283
                    }
284
                    final String count = imported + "/" + tickets.size();
285
                    SwingUtilities.invokeLater(new Runnable() {
286
 
287
                        @Override
288
                        public void run() {
289
                            JOptionPane.showMessageDialog(null, count + " ticket(s) importé(s). Clôture de la caisse terminée.");
290
                        }
291
                    });
292
                    return null;
293
                }
294
            });
295
        } catch (Exception exn) {
296
            ExceptionHandler.handle("Une erreur est survenue pendant la clôture.", exn);
297
        }
298
 
299
    }
300
 
144 ilm 301
    public final int importReceipts(final List<Ticket> tickets, final List<ReceiptEntry> entries) throws SQLException {
302
        if (entries != null && entries.size() != tickets.size())
303
            throw new IllegalArgumentException("Size mismatch");
304
 
305
        final int defaultIDClient = getClientCaisse().getID();
306
        SQLElement elt = Configuration.getInstance().getDirectory().getElement("TICKET_CAISSE");
307
        SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE_ELEMENT");
308
        SQLElement eltEnc = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT");
309
        SQLElement eltMode = Configuration.getInstance().getDirectory().getElement("MODE_REGLEMENT");
310
        SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement("ARTICLE");
311
        final SQLDataSource ds = elt.getTable().getDBSystemRoot().getDataSource();
312
        int imported = 0;
313
 
314
        final Iterator<ReceiptEntry> entriesIter = entries == null ? null : entries.iterator();
315
        for (Ticket ticket : tickets) {
316
            SQLSelect sel = new SQLSelect();
317
            sel.addSelectFunctionStar("COUNT");
318
            sel.setWhere(new Where(elt.getTable().getField("NUMERO"), "=", ticket.getCode()));
319
            // if entries is null, it's the obsolete way when there was no opening/closure
320
            if (entries != null || ((Number) ds.executeScalar(sel.asString())).intValue() == 0) {
321
                final ReceiptEntry entry;
322
                if (entriesIter == null) {
323
                    entry = null;
324
                } else {
325
                    entry = entriesIter.next();
326
                    if (entry == null)
327
                        throw new IllegalArgumentException("Null log entry for " + ticket);
328
                    else if (!entry.getCodeString().equals(ticket.getCode()))
329
                        throw new IllegalArgumentException("Code mismatch for " + ticket);
330
                }
331
 
332
                SQLRowValues rowVals = new SQLRowValues(elt.getTable());
333
                rowVals.put("NUMERO", ticket.getCode());
334
                rowVals.put("DATE", ticket.getCreationDate());
335
                rowVals.put("ID_CAISSE", getPosID());
336
                if (entry != null) {
337
                    rowVals.put("FILE_HASH", entry.getFileHash());
338
                    rowVals.put("FILE_HASH_PREVIOUS", ticket.getPreviousHash());
339
                }
340
                int idClient = ticket.getClient().getId();
341
                if (idClient <= 0) {
342
                    idClient = defaultIDClient;
343
                }
344
                TotalCalculator calc = new TotalCalculator("T_PA_HT", "T_PV_HT", null);
345
 
346
                String val = DefaultNXProps.getInstance().getStringProperty("ArticleService");
347
                Boolean bServiceActive = Boolean.valueOf(val);
348
                calc.setServiceActive(bServiceActive != null && bServiceActive);
349
 
350
                // Articles
351
                for (Pair<Article, Integer> item : ticket.getArticles()) {
352
                    SQLRowValues rowValsElt = new SQLRowValues(eltFact.getTable());
353
                    final Article article = item.getFirst();
354
                    final Integer nb = item.getSecond();
355
                    rowValsElt.put("QTE", nb);
356
                    rowValsElt.put("PV_HT", article.getPriceWithoutTax());
357
                    Float tauxFromId = TaxeCache.getCache().getTauxFromId(article.getIdTaxe());
358
                    BigDecimal tauxTVA = new BigDecimal(tauxFromId).movePointLeft(2).add(BigDecimal.ONE);
359
 
360
                    final BigDecimal valueHT = article.getPriceWithoutTax().multiply(new BigDecimal(nb), DecimalUtils.HIGH_PRECISION);
361
 
362
                    rowValsElt.put("T_PV_HT", valueHT);
363
                    rowValsElt.put("T_PV_TTC", valueHT.multiply(tauxTVA, DecimalUtils.HIGH_PRECISION));
364
                    rowValsElt.put("ID_TAXE", article.getIdTaxe());
365
                    rowValsElt.put("CODE", article.getCode());
366
                    rowValsElt.put("NOM", article.getName());
367
                    rowValsElt.put("ID_TICKET_CAISSE", rowVals);
368
                    rowValsElt.put("ID_ARTICLE", article.getId());
369
                    calc.addLine(rowValsElt, eltArticle.getTable().getRow(article.getId()), 0, false);
370
                }
371
                calc.checkResult();
372
                long longValueTotalHT = calc.getTotalHT().movePointRight(2).setScale(0, RoundingMode.HALF_UP).longValue();
373
                rowVals.put("TOTAL_HT", longValueTotalHT);
374
 
375
                long longValueTotal = calc.getTotalTTC().movePointRight(2).setScale(0, RoundingMode.HALF_UP).longValue();
376
                rowVals.put("TOTAL_TTC", longValueTotal);
377
                long longValueTotalTVA = calc.getTotalTVA().movePointRight(2).setScale(0, RoundingMode.HALF_UP).longValue();
378
                rowVals.put("TOTAL_TVA", longValueTotalTVA);
379
 
380
                // Paiements
381
                for (Paiement paiement : ticket.getPaiements()) {
151 ilm 382
                    if (paiement.getMontantInCents() != 0 && paiement.getType() != Paiement.SOLDE) {
144 ilm 383
 
384
                        SQLRowValues rowValsElt = new SQLRowValues(eltEnc.getTable());
385
                        SQLRowValues rowValsEltMode = new SQLRowValues(eltMode.getTable());
386
                        if (paiement.getType() == Paiement.CB) {
387
                            rowValsEltMode.put("ID_TYPE_REGLEMENT", TypeReglementSQLElement.CB);
388
                        } else if (paiement.getType() == Paiement.CHEQUE) {
389
                            rowValsEltMode.put("ID_TYPE_REGLEMENT", TypeReglementSQLElement.CHEQUE);
390
                        } else if (paiement.getType() == Paiement.ESPECES) {
391
                            rowValsEltMode.put("ID_TYPE_REGLEMENT", TypeReglementSQLElement.ESPECE);
392
                        }
393
 
394
                        rowValsElt.put("ID_MODE_REGLEMENT", rowValsEltMode);
395
                        rowValsElt.put("ID_CLIENT", idClient);
396
 
397
                        long montant = Long.valueOf(paiement.getMontantInCents());
398
                        if (ticket.getPaiements().size() == 1 && paiement.getType() == Paiement.ESPECES) {
399
                            montant = longValueTotal;
400
                        }
401
                        rowValsElt.put("MONTANT", montant);
402
                        rowValsElt.put("NOM", "Ticket " + ticket.getCode());
403
                        rowValsElt.put("DATE", ticket.getCreationDate());
404
                        rowValsElt.put("ID_TICKET_CAISSE", rowVals);
405
 
406
                    }
407
                }
408
 
409
                SQLRow rowFinal = rowVals.insert();
410
                imported++;
411
                GenerationMvtTicketCaisse mvt = new GenerationMvtTicketCaisse(rowFinal);
412
                final Integer idMvt;
413
                try {
414
                    idMvt = mvt.genereMouvement().call();
415
 
416
                    SQLRowValues valTicket = rowFinal.asRowValues();
417
                    valTicket.put("ID_MOUVEMENT", Integer.valueOf(idMvt));
418
                    rowFinal = valTicket.update();
419
 
420
                    // msie à jour du mouvement
421
                    List<SQLRow> rowsEnc = rowFinal.getReferentRows(eltEnc.getTable());
422
                    long totalEnc = 0;
423
                    for (SQLRow sqlRow : rowsEnc) {
424
                        long montant = sqlRow.getLong("MONTANT");
425
                        PrixTTC ttc = new PrixTTC(montant);
426
                        totalEnc += montant;
427
                        new GenerationReglementVenteNG(
428
                                "Règlement " + sqlRow.getForeignRow("ID_MODE_REGLEMENT").getForeignRow("ID_TYPE_REGLEMENT").getString("NOM") + " Ticket " + rowFinal.getString("NUMERO"),
429
                                sqlRow.getForeign("ID_CLIENT"), ttc, sqlRow.getDate("DATE").getTime(), sqlRow.getForeignRow("ID_MODE_REGLEMENT"), rowFinal, rowFinal.getForeignRow("ID_MOUVEMENT"),
430
                                false);
431
                    }
432
                    if (totalEnc > longValueTotal) {
433
                        final SQLTable table = Configuration.getInstance().getDirectory().getElement("TYPE_REGLEMENT").getTable();
434
                        int idComptePceCaisse = table.getRow(TypeReglementSQLElement.ESPECE).getInt("ID_COMPTE_PCE_CLIENT");
435
                        if (idComptePceCaisse == table.getUndefinedID()) {
436
                            idComptePceCaisse = ComptePCESQLElement.getId(ComptePCESQLElement.getComptePceDefault("VenteEspece"));
437
                        }
438
                        new GenerationMvtVirement(idComptePceCaisse, rowFinal.getForeign("ID_CLIENT").getInt("ID_COMPTE_PCE"), 0, totalEnc - longValueTotal,
439
                                "Rendu sur règlement " + " Ticket " + rowFinal.getString("NUMERO"), new Date(), JournalSQLElement.CAISSES, " Ticket " + rowFinal.getString("NUMERO")).genereMouvement();
440
                    }
441
                } catch (Exception exn) {
442
                    exn.printStackTrace();
443
                    throw new SQLException(exn);
444
                }
445
                updateStock(rowFinal.getID());
446
 
447
            }
448
        }
449
        return imported;
450
    }
451
 
132 ilm 452
    private SQLRow rowClient = null;
453
 
454
    private SQLRow getClientCaisse() throws SQLException {
455
        if (rowClient == null) {
456
            SQLElement elt = Configuration.getInstance().getDirectory().getElement("CLIENT");
457
            SQLSelect sel = new SQLSelect();
458
            sel.addSelectStar(elt.getTable());
459
            sel.setWhere(new Where(elt.getTable().getField("NOM"), "=", "Caisse OpenConcerto"));
460
            @SuppressWarnings("unchecked")
461
            List<SQLRow> l = (List<SQLRow>) elt.getTable().getBase().getDataSource().execute(sel.asString(), new SQLSelectHandlerBuilder(sel).createHandler());
462
            if (l.size() > 0) {
463
                rowClient = l.get(0);
464
            } else {
465
                SQLRowValues rowValues = new SQLRowValues(elt.getTable());
466
                rowValues.put("NOM", "Caisse OpenConcerto");
467
                SQLRowValues rowValuesMode = new SQLRowValues(elt.getTable().getTable("MODE_REGLEMENT"));
468
                rowValuesMode.put("ID_TYPE_REGLEMENT", TypeReglementSQLElement.CB);
469
                rowValues.put("ID_MODE_REGLEMENT", rowValuesMode);
470
 
471
                // Select Compte client par defaut
472
                final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
473
                final SQLTable tablePrefCompte = base.getTable("PREFS_COMPTE");
474
                final SQLRow rowPrefsCompte = tablePrefCompte.getRow(2);
475
 
476
                int idDefaultCompteClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_CLIENT");
477
                if (idDefaultCompteClient <= 1) {
478
                    try {
479
                        idDefaultCompteClient = ComptePCESQLElement.getIdComptePceDefault("Clients");
480
                    } catch (Exception e) {
481
                        e.printStackTrace();
482
                    }
483
                }
484
 
485
                rowValues.put("ID_COMPTE_PCE", idDefaultCompteClient);
486
                rowClient = rowValues.insert();
487
            }
488
        }
489
        return rowClient;
490
 
491
    }
492
 
493
    private void updateStock(int id) throws SQLException {
494
        final SQLRow row = getClientCaisse().getTable().getTable("TICKET_CAISSE").getRow(id);
495
        StockItemsUpdater stockUpdater = new StockItemsUpdater(new StockLabel() {
496
            @Override
497
            public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
498
                return "Ticket N°" + rowOrigin.getString("NUMERO");
499
            }
500
        }, row, row.getReferentRows(getClientCaisse().getTable().getTable("SAISIE_VENTE_FACTURE_ELEMENT")), TypeStockUpdate.REAL_DELIVER);
501
        stockUpdater.update();
502
    }
503
 
504
    public List<Ticket> allTickets() {
505
        final List<Ticket> l = new ArrayList<Ticket>();
506
        for (final File f : ReceiptCode.getReceiptsToImport(getPosID())) {
144 ilm 507
            // old receipts have no hash files
508
            final Ticket ticket = Ticket.parseFile(f, HashMode.NOT_REQUIRED);
132 ilm 509
            if (ticket != null) {
510
                l.add(ticket);
511
            }
512
        }
513
        return l;
514
    }
515
 
516
    public List<TicketLine> getHeaderLines() {
517
        return headerLines;
518
    }
519
 
520
    public void setHeaderLines(List<TicketLine> headerLines) {
521
        this.headerLines = headerLines;
522
    }
523
 
524
    public List<TicketLine> getFooterLines() {
525
        return footerLines;
526
    }
527
 
528
    public void setFooterLines(List<TicketLine> footerLines) {
529
        this.footerLines = footerLines;
530
    }
531
 
532
    private void loadConfiguration() {
533
        if (!isConfigurationFileCreated()) {
534
            System.err.println("POSConfiguration.loadConfigurationFromXML() configuration not loaded. " + getConfigFile().getAbsolutePath() + " missing.");
535
            return;
536
        }
537
 
538
        final SAXBuilder builder = new SAXBuilder();
539
        File file = getConfigFile();
540
 
541
        try {
542
            System.out.println("POSConfiguration.loadConfigurationFromXML() loading " + file.getAbsolutePath());
543
            Document document = builder.build(file);
544
            // config
545
            final Element rootElement = document.getRootElement();
546
            setUserID(Integer.valueOf(rootElement.getAttributeValue("userID", "2")));
547
            setCompanyID(Integer.valueOf(rootElement.getAttributeValue("societeID", "42")));
548
            setPosID(Integer.valueOf(rootElement.getAttributeValue("caisseID", "2")));
549
            setScanDelay(Integer.valueOf(rootElement.getAttributeValue("scanDelay", "80")));
550
            // screen
551
            final List<Element> children = rootElement.getChildren("screen");
552
            if (children != null) {
553
                for (Element e : children) {
554
                    this.screenWidth = Integer.valueOf(e.getAttributeValue("width", "0"));
555
                    this.screenHeight = Integer.valueOf(e.getAttributeValue("height", "0"));
556
                }
557
            }
558
            // credit card
559
            final List<Element> childrenCreditCard = rootElement.getChildren("creditcard");
560
            if (childrenCreditCard != null) {
561
                for (Element e : childrenCreditCard) {
562
                    this.creditCardPort = e.getAttributeValue("port", "");
563
                }
564
            }
142 ilm 565
            // lcd
132 ilm 566
            final List<Element> childrenLCD = rootElement.getChildren("lcd");
567
            if (childrenLCD != null) {
568
                for (Element e : childrenLCD) {
142 ilm 569
                    this.LCDType = e.getAttributeValue("type", "serial");
570
                    this.LCDPort = e.getAttributeValue("port", "");
132 ilm 571
                    this.LCDLine1 = e.getAttributeValue("line1", "");
572
                    this.LCDLine2 = e.getAttributeValue("line2", "");
573
                }
574
            }
575
 
576
            // header
577
            final List<Element> headers = rootElement.getChildren("header");
578
            if (headers != null) {
579
                for (Element header : headers) {
580
                    this.headerLines.add(new TicketLine(header.getValue(), header.getAttributeValue("style")));
581
                }
582
            }
583
            // footer
584
            final List<Element> footers = rootElement.getChildren("footer");
585
            if (footers != null) {
586
                for (Element header : footers) {
587
                    this.footerLines.add(new TicketLine(header.getValue(), header.getAttributeValue("style")));
588
                }
589
            }
590
            // ticket printers
591
            final List<Element> printers = rootElement.getChildren("ticketPrinter");
592
            if (printers.size() > 0) {
593
                configureTicketPrinter(this.ticketPrinterConf1, printers.get(0));
594
            }
595
            if (printers.size() > 1) {
596
                configureTicketPrinter(this.ticketPrinterConf2, printers.get(1));
597
            }
598
        } catch (Exception e) {
599
            e.printStackTrace();
600
        }
601
 
602
    }
603
 
604
    private void configureTicketPrinter(TicketPrinterConfiguration conf, Element element) {
605
        conf.setType(element.getAttributeValue("type"));
606
        conf.setName(element.getAttributeValue("name"));
607
        conf.setCopyCount(Integer.parseInt(element.getAttributeValue("copyCount")));
608
        conf.setTicketWidth(Integer.parseInt(element.getAttributeValue("ticketWidth")));
609
        conf.setFolder(element.getAttributeValue("folder", ""));
610
    }
611
 
612
    private Element getElementFromConfiguration(TicketPrinterConfiguration conf) {
613
        final Element element = new Element("ticketPrinter");
614
        element.setAttribute("type", conf.getType());
615
        element.setAttribute("name", conf.getName());
616
        element.setAttribute("copyCount", String.valueOf(conf.getCopyCount()));
617
        element.setAttribute("ticketWidth", String.valueOf(conf.getTicketWidth()));
618
        element.setAttribute("folder", conf.getFolder());
619
        return element;
620
    }
621
 
622
    public void saveConfiguration() {
623
        final File file = getConfigFile();
144 ilm 624
        if (file.exists() && !file.canWrite()) {
625
            JOptionPane.showMessageDialog(null, "Impossible d'enregistrer le fichier : " + file.getAbsolutePath() + "\nMerci d'accorder les droits d'écriture à ce fichier.");
626
            return;
627
        }
132 ilm 628
        final XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
629
        try {
630
            System.out.println("Saving:" + file.getAbsolutePath());
631
            final FileOutputStream fileOutputStream = new FileOutputStream(file);
632
            final Document doc = new Document();
633
            final Element configElement = new Element("config");
634
            configElement.setAttribute("userID", String.valueOf(this.userID));
635
            configElement.setAttribute("societeID", String.valueOf(this.companyID));
636
            configElement.setAttribute("caisseID", String.valueOf(this.posID));
637
            configElement.setAttribute("scanDelay", String.valueOf(this.scanDelay));
638
            doc.addContent(configElement);
639
            // screen size
640
            final Element screenElement = new Element("screen");
641
            screenElement.setAttribute("width", String.valueOf(this.screenWidth));
642
            screenElement.setAttribute("height", String.valueOf(this.screenHeight));
643
            configElement.addContent(screenElement);
644
            // credit card
645
            final Element creditCardElement = new Element("creditcard");
646
            creditCardElement.setAttribute("port", this.creditCardPort);
647
            configElement.addContent(creditCardElement);
648
            // LCD
649
            final Element lcdElement = new Element("lcd");
142 ilm 650
            lcdElement.setAttribute("type", this.LCDType);
651
            lcdElement.setAttribute("port", this.LCDPort);
132 ilm 652
            lcdElement.setAttribute("line1", this.LCDLine1);
653
            lcdElement.setAttribute("line2", this.LCDLine2);
654
            configElement.addContent(lcdElement);
655
 
656
            // header
657
            for (TicketLine line : this.headerLines) {
658
                Element e = new Element("header");
659
                final String style = line.getStyle();
660
                if (style != null && !style.isEmpty()) {
661
                    e.setAttribute("style", style);
662
                }
663
                e.setText(line.getText());
664
                configElement.addContent(e);
665
            }
666
            // footer
667
            for (TicketLine line : this.footerLines) {
668
                Element e = new Element("footer");
669
                final String style = line.getStyle();
670
                if (style != null && !style.isEmpty()) {
671
                    e.setAttribute("style", style);
672
                }
673
                e.setText(line.getText());
674
                configElement.addContent(e);
675
            }
676
            // ticket printer
677
            configElement.addContent(getElementFromConfiguration(this.ticketPrinterConf1));
678
            configElement.addContent(getElementFromConfiguration(this.ticketPrinterConf2));
679
            outputter.output(doc, fileOutputStream);
680
            fileOutputStream.close();
681
        } catch (Exception e) {
682
            e.printStackTrace();
683
            ExceptionHandler.handle("Erreur lors de la sauvegarde de la configuration de la caisse.\n" + file.getAbsolutePath());
684
        }
685
 
686
    }
687
 
149 ilm 688
    public void print(Printable ticket) {
151 ilm 689
        print(ticket, 0);
132 ilm 690
    }
691
 
151 ilm 692
    public void print(Printable ticket, int additionnalCopy) {
693
        print(ticket, this.ticketPrinterConf1, additionnalCopy);
694
        print(ticket, this.ticketPrinterConf2, additionnalCopy);
695
    }
696
 
149 ilm 697
    public void printOnceOnFirstPrinter(Printable ticket) {
698
        if (this.ticketPrinterConf1.isValid()) {
699
            final TicketPrinter prt = this.ticketPrinterConf1.createTicketPrinter();
700
            ticket.print(prt, this.ticketPrinterConf1.getTicketWidth());
701
        }
702
    }
703
 
704
    public void print(Printable ticket, TicketPrinterConfiguration conf) {
151 ilm 705
        print(ticket, conf, 0);
706
    }
707
 
708
    public void print(Printable ticket, TicketPrinterConfiguration conf, int additionnalCopy) {
709
        int copyCount = conf.getCopyCount() + additionnalCopy;
710
        if (conf.isValid() && copyCount > 0) {
132 ilm 711
            final TicketPrinter prt = conf.createTicketPrinter();
151 ilm 712
            for (int i = 0; i < copyCount; i++) {
132 ilm 713
                ticket.print(prt, conf.getTicketWidth());
714
            }
715
        }
716
    }
717
 
718
    public boolean isUsingJPos() {
719
        // TODO Auto-generated method stub
720
        return false;
721
    }
722
 
723
    public List<String> getJPosDirectories() {// TODO Auto-generated method stub
724
        final ArrayList<String> result = new ArrayList<String>();
725
        return result;
726
    }
727
 
142 ilm 728
    public String getLCDPort() {
729
        return LCDPort;
132 ilm 730
    }
731
 
142 ilm 732
    public void setLCDPort(String port) {
733
        this.LCDPort = port;
132 ilm 734
    }
735
 
736
    public String getLCDLine1() {
737
        return this.LCDLine1;
738
    }
739
 
740
    public void setLCDLine1(String text) {
741
        this.LCDLine1 = text;
742
    }
743
 
744
    public String getLCDLine2() {
745
        return this.LCDLine2;
746
    }
747
 
748
    public void setLCDLine2(String text) {
749
        this.LCDLine2 = text;
750
    }
751
 
142 ilm 752
    public List<Client> allClients() {
753
        SQLElement elt = Configuration.getInstance().getDirectory().getElement("CLIENT");
754
        SQLRowValues r = new SQLRowValues(elt.getTable());
755
        r.putNulls("NOM", "SOLDE_COMPTE");
756
        SQLRowValues rAdresse = new SQLRowValues(Configuration.getInstance().getDirectory().getElement("ADRESSE").getTable());
757
        rAdresse.putNulls("RUE", "VILLE");
758
        r.put("ID_ADRESSE", rAdresse);
759
        SQLRowValuesListFetcher f = new SQLRowValuesListFetcher(r);
760
        List<SQLRowValues> result = f.fetch();
761
        List<Client> l = new ArrayList<Client>();
762
 
763
        for (SQLRowValues sqlRowValues : result) {
764
            Client c = new Client(sqlRowValues.getID(), sqlRowValues.getString("NOM"), sqlRowValues.getBigDecimal("SOLDE_COMPTE"));
765
            final SQLRowAccessor foreign = sqlRowValues.getForeign("ID_ADRESSE");
766
            c.setAdresse(foreign.getString("RUE") + " " + foreign.getString("VILLE"));
767
            l.add(c);
768
        }
769
        Collections.sort(l, new Comparator<Client>() {
770
 
771
            @Override
772
            public int compare(Client o1, Client o2) {
773
                return o1.getFullName().compareToIgnoreCase(o2.getFullName());
774
            }
775
        });
776
        l.add(0, Client.NONE);
777
        return l;
778
    }
779
 
780
    public void setLCDType(String type) {
781
        this.LCDType = type;
782
 
783
    }
784
 
785
    public String getLCDType() {
786
        return this.LCDType;
787
    }
132 ilm 788
}