OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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