OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 144 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 144 Rev 149
Line 19... Line 19...
19
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status;
19
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status;
20
import org.openconcerto.utils.CompareUtils;
20
import org.openconcerto.utils.CompareUtils;
21
import org.openconcerto.utils.FileUtils;
21
import org.openconcerto.utils.FileUtils;
22
import org.openconcerto.utils.MessageDigestUtils;
22
import org.openconcerto.utils.MessageDigestUtils;
23
import org.openconcerto.utils.StringUtils;
23
import org.openconcerto.utils.StringUtils;
-
 
24
import org.openconcerto.utils.TimeUtils;
24
import org.openconcerto.utils.cc.ExnTransformer;
25
import org.openconcerto.utils.cc.ExnTransformer;
25
import org.openconcerto.utils.checks.ValidState;
26
import org.openconcerto.utils.checks.ValidState;
26
 
27
 
27
import java.io.BufferedInputStream;
28
import java.io.BufferedInputStream;
28
import java.io.IOException;
29
import java.io.IOException;
Line 228... Line 229...
228
    public final Path getReceiptFile(final ReceiptCode code) throws IOException {
229
    public final Path getReceiptFile(final ReceiptCode code) throws IOException {
229
        final Path dayDirToUse = getDayDirToUse(getDayDir(code.getDay(), false));
230
        final Path dayDirToUse = getDayDirToUse(getDayDir(code.getDay(), false));
230
        return dayDirToUse == null ? null : dayDirToUse.resolve(code.getFileName());
231
        return dayDirToUse == null ? null : dayDirToUse.resolve(code.getFileName());
231
    }
232
    }
232
 
233
 
-
 
234
    public final Path getLogFile(final Calendar day) throws IOException {
-
 
235
        return getLogFile(getDayDir(day, false));
-
 
236
    }
-
 
237
 
-
 
238
    private final Path getLogFile(final Path dayDir) throws IOException {
-
 
239
        final Path dayDirToUse = getDayDirToUse(dayDir);
-
 
240
        return dayDirToUse == null ? null : dayDirToUse.resolve(LOG_FILENAME);
-
 
241
    }
-
 
242
 
233
    public final int getPosID() {
243
    public final int getPosID() {
234
        return this.posID;
244
        return this.posID;
235
    }
245
    }
236
 
246
 
237
    public <T, Exn extends Exception> T doWithLock(final ExnTransformer<RegisterFiles, T, Exn> transf) throws IOException, Exn {
247
    public <T, Exn extends Exception> T doWithLock(final ExnTransformer<RegisterFiles, T, Exn> transf) throws IOException, Exn {
Line 303... Line 313...
303
        return sortedPaths;
313
        return sortedPaths;
304
    }
314
    }
305
 
315
 
306
    private Path getLogToUse(final SortedSet<Path> sortedDays) throws IOException {
316
    private Path getLogToUse(final SortedSet<Path> sortedDays) throws IOException {
307
        for (final Path dayDir : sortedDays) {
317
        for (final Path dayDir : sortedDays) {
308
            final Path dayDirToUse = getDayDirToUse(dayDir);
318
            final Path logFile = getLogFile(dayDir);
309
            if (dayDirToUse != null)
319
            if (logFile != null)
310
                return dayDirToUse.resolve(LOG_FILENAME);
320
                return logFile;
311
        }
321
        }
312
        return null;
322
        return null;
313
    }
323
    }
314
 
324
 
315
    public final List<Path> findLogFiles() throws IOException {
325
    public final List<Path> findLogFiles() throws IOException {
316
        final List<Path> res = new ArrayList<>();
326
        final List<Path> res = new ArrayList<>();
317
        for (final Path dayDir : getSortedDays(true)) {
327
        for (final Path dayDir : getSortedDays(true)) {
318
            final Path dayDirToUse = getDayDirToUse(dayDir);
328
            final Path logFile = getLogFile(dayDir);
319
            if (dayDirToUse != null)
329
            if (logFile != null)
320
                res.add(dayDirToUse.resolve(LOG_FILENAME));
330
                res.add(logFile);
321
        }
331
        }
322
        return res;
332
        return res;
323
    }
333
    }
324
 
334
 
325
    private final Path getDayDirToUse(final Path dayDir) throws IOException {
335
    private final Path getDayDirToUse(final Path dayDir) throws IOException {
Line 364... Line 374...
364
            public RegisterLog transformChecked(RegisterFiles input) throws IOException {
374
            public RegisterLog transformChecked(RegisterFiles input) throws IOException {
365
                POSConfiguration.getLogger().log(Level.FINE, "Begin opening of FS state for register {0}", input.getPosID());
375
                POSConfiguration.getLogger().log(Level.FINE, "Begin opening of FS state for register {0}", input.getPosID());
366
                POSConfiguration.checkRegisterID(input.getPosID(), registerDB.getPosID());
376
                POSConfiguration.checkRegisterID(input.getPosID(), registerDB.getPosID());
367
                final RegisterLog lastLog = input.checkStatus(true);
377
                final RegisterLog lastLog = input.checkStatus(true);
368
                final String lastLocalHash;
378
                final String lastLocalHash;
-
 
379
                final Date prevDate;
369
                if (lastLog == null) {
380
                if (lastLog == null) {
370
                    lastLocalHash = null;
381
                    lastLocalHash = null;
-
 
382
                    prevDate = null;
371
                } else {
383
                } else {
372
                    try {
384
                    try {
373
                        lastLocalHash = lastLog.getLastReceiptHash();
385
                        lastLocalHash = lastLog.getLastReceiptHash();
374
                    } catch (ParseException e) {
386
                    } catch (ParseException e) {
375
                        throw new IOException("Couldn't parse last receipt of log", e);
387
                        throw new IOException("Couldn't parse last receipt of log", e);
376
                    }
388
                    }
-
 
389
                    prevDate = lastLog.getFirstRegisterEvent().getDate();
-
 
390
                    if (lastLocalHash != null && prevDate == null)
-
 
391
                        throw new IOException("There's a receipt, but no previous closure date");
377
                }
392
                }
378
 
393
 
379
                final DBState dbState;
394
                final DBState dbState;
380
                if (passedDBState == null) {
395
                if (passedDBState == null) {
381
                    try {
396
                    try {
Line 404... Line 419...
404
                FileUtils.rm_R(stagingDir);
419
                FileUtils.rm_R(stagingDir);
405
                FileUtils.rm_R(currentDir);
420
                FileUtils.rm_R(currentDir);
406
                FileUtils.rm_R(prevDir);
421
                FileUtils.rm_R(prevDir);
407
                Files.createDirectory(stagingDir);
422
                Files.createDirectory(stagingDir);
408
 
423
 
409
                final Element rootElem = new Element("registerLog");
424
                final Element rootElem = RegisterLog.createRootElement();
410
                rootElem.addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_OPENING, cal.getTime(), userID, input.getPosID(), lastLocalHash).toXML());
425
                rootElem.addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_OPENING, cal.getTime(), userID, input.getPosID(), lastLocalHash, prevDate).toXML());
411
                save(new Document(rootElem), stagingDir.resolve(LOG_FILENAME));
426
                save(new Document(rootElem), stagingDir.resolve(LOG_FILENAME));
412
 
427
 
413
                Files.move(stagingDir, currentDir, StandardCopyOption.ATOMIC_MOVE);
428
                Files.move(stagingDir, currentDir, StandardCopyOption.ATOMIC_MOVE);
414
 
429
 
415
                POSConfiguration.getLogger().log(Level.INFO, "Finished opening of FS state for register {0}", registerDB);
430
                POSConfiguration.getLogger().log(Level.INFO, "Finished opening of FS state for register {0}", registerDB);
Line 505... Line 520...
505
                } catch (ParseException e) {
520
                } catch (ParseException e) {
506
                    throw new IOException("Couldn't find last receipt hash", e);
521
                    throw new IOException("Couldn't find last receipt hash", e);
507
                }
522
                }
508
                // TODO verify that receipts' files match the log's content
523
                // TODO verify that receipts' files match the log's content
509
                final Document doc = lastLog.getDocument().clone();
524
                final Document doc = lastLog.getDocument().clone();
510
                doc.getRootElement().addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_CLOSURE, new Date(), userID, getPosID(), lastHash).toXML());
525
                doc.getRootElement().addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_CLOSURE, new Date(), userID, getPosID(), lastHash, null).toXML());
511
                save(doc, stagingDir.resolve(LOG_FILENAME));
526
                save(doc, stagingDir.resolve(LOG_FILENAME));
512
                return null;
527
                return null;
513
            }
528
            }
514
 
529
 
515
            @Override
530
            @Override
Line 522... Line 537...
522
                }
537
                }
523
            }
538
            }
524
        });
539
        });
525
    }
540
    }
526
 
541
 
-
 
542
    public static final class DifferentDayException extends IllegalStateException {
-
 
543
        protected DifferentDayException(final RegisterLog lastLog) {
-
 
544
            super("Cannot save a receipt for a different day than the register opening : " + lastLog.getFirstRegisterEvent());
-
 
545
        }
-
 
546
    }
-
 
547
 
527
    public final String save(final Ticket t) throws IOException, SQLException {
548
    public final String save(final Ticket t) throws IOException, SQLException {
528
        return this.doWithLock(new UpdateDir<String, String>("saving receipt") {
549
        return this.doWithLock(new UpdateDir<String, String>("saving receipt") {
529
            @Override
550
            @Override
530
            protected boolean needsClosed() {
551
            protected boolean needsClosed() {
531
                return false;
552
                return false;
532
            }
553
            }
533
 
554
 
534
            @Override
555
            @Override
535
            protected String updateDir(final Path stagingDir, final RegisterLog lastLog) throws IOException {
556
            protected String updateDir(final Path stagingDir, final RegisterLog lastLog) throws IOException {
-
 
557
                if (!TimeUtils.isSameDay(t.getCreationCal(), lastLog.getFirstRegisterEvent().getDate()))
-
 
558
                    throw new DifferentDayException(lastLog);
536
                try {
559
                try {
537
                    final ReceiptEntry lastReceipt = lastLog.getLastReceiptCreationEvent();
560
                    final ReceiptEntry lastReceipt = lastLog.getLastReceiptCreationEvent();
538
                    final int expectedIndex;
561
                    final int expectedIndex;
539
                    final String expectedHash = lastLog.getLastReceiptHash();
562
                    final String expectedHash = lastLog.getLastReceiptHash();
540
                    if (lastReceipt == null) {
563
                    if (lastReceipt == null) {