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 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 151 Rev 156
Line 24... Line 24...
24
import org.openconcerto.erp.core.sales.pos.model.RegisterFiles;
24
import org.openconcerto.erp.core.sales.pos.model.RegisterFiles;
25
import org.openconcerto.erp.core.sales.pos.model.RegisterLog;
25
import org.openconcerto.erp.core.sales.pos.model.RegisterLog;
26
import org.openconcerto.erp.core.sales.pos.model.RegisterState;
26
import org.openconcerto.erp.core.sales.pos.model.RegisterState;
27
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status;
27
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status;
28
import org.openconcerto.erp.core.sales.pos.model.Ticket;
28
import org.openconcerto.erp.core.sales.pos.model.Ticket;
-
 
29
import org.openconcerto.erp.utils.TM;
29
import org.openconcerto.sql.PropsConfiguration;
30
import org.openconcerto.sql.PropsConfiguration;
30
import org.openconcerto.sql.RemoteShell;
31
import org.openconcerto.sql.RemoteShell;
31
import org.openconcerto.sql.element.SQLElementDirectory;
32
import org.openconcerto.sql.element.SQLElementDirectory;
32
import org.openconcerto.sql.model.SQLBase;
33
import org.openconcerto.sql.model.SQLBase;
33
import org.openconcerto.sql.model.SQLRowAccessor;
34
import org.openconcerto.sql.model.SQLRowAccessor;
34
import org.openconcerto.sql.model.SQLRowValues;
35
import org.openconcerto.sql.model.SQLRowValues;
-
 
36
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
35
import org.openconcerto.sql.sqlobject.ElementComboBox;
37
import org.openconcerto.sql.sqlobject.ElementComboBox;
36
import org.openconcerto.utils.ClassPathLoader;
38
import org.openconcerto.utils.ClassPathLoader;
37
import org.openconcerto.utils.ExceptionHandler;
39
import org.openconcerto.utils.ExceptionHandler;
38
import org.openconcerto.utils.cc.ExnTransformer;
40
import org.openconcerto.utils.cc.ExnTransformer;
39
 
41
 
Line 48... Line 50...
48
import java.net.MalformedURLException;
50
import java.net.MalformedURLException;
49
import java.sql.SQLException;
51
import java.sql.SQLException;
50
import java.text.ParseException;
52
import java.text.ParseException;
51
import java.util.EnumSet;
53
import java.util.EnumSet;
52
import java.util.List;
54
import java.util.List;
-
 
55
import java.util.Objects;
53
import java.util.Set;
56
import java.util.Set;
54
import java.util.concurrent.Callable;
57
import java.util.concurrent.Callable;
55
import java.util.concurrent.FutureTask;
58
import java.util.concurrent.FutureTask;
56
import java.util.logging.Level;
59
import java.util.logging.Level;
-
 
60
import java.util.logging.Logger;
57
 
61
 
58
import javax.swing.JFrame;
62
import javax.swing.JFrame;
59
import javax.swing.JOptionPane;
63
import javax.swing.JOptionPane;
60
import javax.swing.JPanel;
64
import javax.swing.JPanel;
61
import javax.swing.SwingUtilities;
65
import javax.swing.SwingUtilities;
62
import javax.swing.ToolTipManager;
66
import javax.swing.ToolTipManager;
63
 
67
 
64
import org.jdom2.JDOMException;
68
import org.jdom2.JDOMException;
65
 
69
 
66
public class CaisseFrame extends JFrame {
70
public class CaisseFrame extends JFrame {
-
 
71
    private final POSConfiguration posConf;
67
    private final ComptaPropsConfiguration conf;
72
    private final ComptaPropsConfiguration conf;
68
    private final RegisterFiles files;
73
    private final RegisterFiles files;
69
    private final RegisterDB registerDB;
74
    private final RegisterDB registerDB;
70
    final CaissePanel mainPanel;
75
    final CaissePanel mainPanel;
71
 
76
 
72
    CaisseFrame(final ComptaPropsConfiguration conf, final RegisterFiles files, final RegisterDB registerDB) throws Exception {
77
    CaisseFrame(final POSConfiguration posConf, final ComptaPropsConfiguration conf, final RegisterFiles files, final RegisterDB registerDB) throws Exception {
-
 
78
        this.posConf = posConf;
73
        this.conf = conf;
79
        this.conf = conf;
74
        this.files = files;
80
        this.files = files;
75
        this.registerDB = registerDB;
81
        this.registerDB = registerDB;
76
        this.mainPanel = new CaissePanel(this);
82
        this.mainPanel = new CaissePanel(this);
77
        setContentPane(mainPanel);
83
        setContentPane(mainPanel);
78
        setFocusable(true);
84
        setFocusable(true);
79
    }
85
    }
80
 
86
 
-
 
87
    public final POSConfiguration getPOSConf() {
-
 
88
        return this.posConf;
-
 
89
    }
-
 
90
 
81
    public final ComptaPropsConfiguration getConf() {
91
    public final ComptaPropsConfiguration getConf() {
82
        return this.conf;
92
        return this.conf;
83
    }
93
    }
84
 
94
 
85
    public final RegisterFiles getFiles() {
95
    public final RegisterFiles getFiles() {
Line 105... Line 115...
105
            ExceptionHandler.setThrowableHandler(Gestion.createDefaultThrowableHandler());
115
            ExceptionHandler.setThrowableHandler(Gestion.createDefaultThrowableHandler());
106
            // SpeedUp Linux
116
            // SpeedUp Linux
107
            System.setProperty("sun.java2d.pmoffscreen", "false");
117
            System.setProperty("sun.java2d.pmoffscreen", "false");
108
            System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
118
            System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
109
            System.setProperty(PropsConfiguration.REDIRECT_TO_FILE, "true");
119
            System.setProperty(PropsConfiguration.REDIRECT_TO_FILE, "true");
-
 
120
            final POSConfiguration posConf = POSConfiguration.setInstance();
110
            if (POSConfiguration.getInstance().isUsingJPos()) {
121
            if (posConf.isUsingJPos()) {
111
                ClassPathLoader c = ClassPathLoader.getInstance();
122
                ClassPathLoader c = ClassPathLoader.getInstance();
112
                try {
123
                try {
113
                    final List<String> posDirectories = POSConfiguration.getInstance().getJPosDirectories();
124
                    final List<String> posDirectories = posConf.getJPosDirectories();
114
                    for (String posDirectory : posDirectories) {
125
                    for (String posDirectory : posDirectories) {
115
                        if (posDirectory != null && !posDirectory.trim().isEmpty()) {
126
                        if (posDirectory != null && !posDirectory.trim().isEmpty()) {
116
                            c.addJarFromDirectory(new File(posDirectory.trim()));
127
                            c.addJarFromDirectory(new File(posDirectory.trim()));
117
                        }
128
                        }
118
                    }
129
                    }
Line 120... Line 131...
120
                    e.printStackTrace();
131
                    e.printStackTrace();
121
                }
132
                }
122
                c.load();
133
                c.load();
123
 
134
 
124
            }
135
            }
125
            final ComptaPropsConfiguration conf = POSConfiguration.getInstance().createConnexion();
136
            final ComptaPropsConfiguration conf = posConf.createConnexion();
126
 
-
 
127
            final int userID = POSConfiguration.getInstance().getUserID();
-
 
128
            final RegisterFiles registerFiles = new RegisterFiles(POSConfiguration.getInstance().getRootDir(), true, POSConfiguration.getInstance().getPosID());
-
 
129
            final RegisterDB registerDB = new RegisterDB(conf.getDirectory(), conf.getProductInfo(), POSConfiguration.getInstance().getPosID());
-
 
130
 
137
 
-
 
138
            final int userID = posConf.getUserID();
-
 
139
            final int posID = posConf.getPosID();
-
 
140
            final RegisterFiles registerFiles = new RegisterFiles(posConf.getRootDir(), true, posConf.getPosID());
-
 
141
            final RegisterDB registerDB = new RegisterDB(conf.getDirectory(), conf.getProductInfo(), posConf.getPosID());
-
 
142
            // check if register exists
-
 
143
            final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(new SQLRowValues(registerDB.getRegisterTable()));
-
 
144
            if (fetcher.fetchOne(posID) == null) {
-
 
145
                SwingUtilities.invokeLater(() -> {
-
 
146
                    JOptionPane.showMessageDialog(null, TM.tr("register.missing", posID), TM.tr("register.missing.title"), JOptionPane.ERROR_MESSAGE);
-
 
147
                });
-
 
148
                posConf.closeConnexion();
-
 
149
                return;
-
 
150
            }
131
            // check before changing any state
151
            // check before changing any state
132
            final boolean quit = registerDB.fetchRegisterState().checkIfMoved();
152
            final boolean quit = registerDB.fetchRegisterState().checkIfMoved();
133
            if (quit) {
153
            if (quit) {
134
                quit();
154
                quit(posConf);
135
                return;
155
                return;
136
            }
156
            }
137
 
157
 
138
            final RegisterState reconciledState = registerFiles.doWithLock(new ExnTransformer<RegisterFiles, RegisterState, IOException>() {
-
 
139
                @Override
158
            final Logger logger = POSConfiguration.getLogger();
140
                public RegisterState transformChecked(RegisterFiles input) throws IOException {
159
            final RegisterState reconciledState;
141
                    try {
160
            try {
142
                        return reconcileFSandDB(conf.getDirectory(), input, registerDB, userID);
161
                reconciledState = registerFiles.doWithLock(new ExnTransformer<RegisterFiles, RegisterState, Exception>() {
143
                    } catch (Exception e) {
162
                    @Override
-
 
163
                    public RegisterState transformChecked(RegisterFiles input) throws Exception {
144
                        throw new IOException("Couldn't reconcile local and remote state", e);
164
                        return reconcileFSandDB(posConf, conf.getDirectory(), input, registerDB);
145
                    }
165
                    }
-
 
166
                });
-
 
167
            } catch (ReconcileException re) {
-
 
168
                logger.log(Level.WARNING, "States couldn’t be reconciled, local : " + re.getLocalState() + ", remote : " + re.getRemoteState(), re);
-
 
169
                final String generalMsg;
-
 
170
                boolean onlyOptionPane = false;
-
 
171
                if (re instanceof OutsideMeddlingException) {
-
 
172
                    generalMsg = TM.tr("register.notReconciled.outsideMeddling") + '\n';
-
 
173
                    onlyOptionPane = true;
-
 
174
                } else if (re instanceof ResumeException) {
-
 
175
                    generalMsg = TM.tr("register.notReconciled.resumeFailed") + '\n';
-
 
176
                } else {
-
 
177
                    generalMsg = "";
146
                }
178
                }
-
 
179
                final String message = TM.getTM().trM("register.notReconciled." + re.getTranslationKey(), "localDate", re.getLocalState().copyDate(), "remoteDate", re.getRemoteState().copyDate());
-
 
180
                if (onlyOptionPane) {
-
 
181
                    SwingUtilities.invokeLater(() -> {
-
 
182
                        JOptionPane.showMessageDialog(null, generalMsg + message, TM.tr("register.notReconciled.title"), JOptionPane.ERROR_MESSAGE);
147
            });
183
                    });
-
 
184
                } else {
-
 
185
                    ExceptionHandler.handle(generalMsg + message, re);
-
 
186
                }
-
 
187
                // ATTN this calls ComptaPropsConfiguration.tearDownLogging(), so even syserr is
-
 
188
                // closed.
-
 
189
                posConf.closeConnexion();
-
 
190
                return;
-
 
191
            } catch (Exception e) {
-
 
192
                throw new IOException("Couldn't reconcile local and remote state", e);
-
 
193
            }
148
            POSConfiguration.getLogger().log(Level.INFO, "FS and DB states reconciled : {0}", reconciledState);
194
            logger.log(Level.INFO, "FS and DB states reconciled : {0}", reconciledState);
149
 
195
 
150
            System.setProperty("awt.useSystemAAFontSettings", "on");
196
            System.setProperty("awt.useSystemAAFontSettings", "on");
151
            System.setProperty("swing.aatext", "true");
197
            System.setProperty("swing.aatext", "true");
152
            System.setProperty(ElementComboBox.CAN_MODIFY, "true");
198
            System.setProperty(ElementComboBox.CAN_MODIFY, "true");
153
 
199
 
Line 167... Line 213...
167
                    final RegisterLog newLog = registerFiles.open(userID, registerDB);
213
                    final RegisterLog newLog = registerFiles.open(userID, registerDB);
168
                    state = newLog.getRegisterState();
214
                    state = newLog.getRegisterState();
169
                }
215
                }
170
            }
216
            }
171
            if (state.getStatus() != Status.OPEN) {
217
            if (state.getStatus() != Status.OPEN) {
172
                POSConfiguration.getLogger().log(Level.FINE, "State not open ({0}), exiting", state);
218
                logger.log(Level.FINE, "State not open ({0}), exiting", state);
173
                POSConfiguration.getInstance().closeConnexion();
219
                posConf.closeConnexion();
174
                return;
220
                return;
175
            }
221
            }
176
            POSConfiguration.getLogger().log(Level.INFO, "FS and DB states open, opening UI");
222
            logger.log(Level.INFO, "FS and DB states open, opening UI");
177
 
223
 
178
            SwingUtilities.invokeLater(new Runnable() {
224
            SwingUtilities.invokeLater(new Runnable() {
179
                public void run() {
225
                public void run() {
180
 
226
 
181
                    try {
227
                    try {
182
                        // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
228
                        // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
183
                    } catch (Exception e) {
229
                    } catch (Exception e) {
184
                        e.printStackTrace();
230
                        e.printStackTrace();
185
                    }
231
                    }
186
                    try {
232
                    try {
187
                        CaisseFrame f = new CaisseFrame(conf, registerFiles, registerDB);
233
                        CaisseFrame f = new CaisseFrame(posConf, conf, registerFiles, registerDB);
188
                        f.setUndecorated(true);
234
                        f.setUndecorated(true);
189
                        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
235
                        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
190
 
236
 
191
                        f.pack();
237
                        f.pack();
192
                        if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
238
                        if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
193
                            f.setLocation(0, 24);
239
                            f.setLocation(0, 24);
194
                        } else {
240
                        } else {
195
                            f.setLocation(0, 0);
241
                            f.setLocation(0, 0);
196
                        }
242
                        }
197
                        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
243
                        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
198
                        if (POSConfiguration.getInstance().getScreenWidth() > 0 && POSConfiguration.getInstance().getScreenHeight() > 0) {
244
                        if (posConf.getScreenWidth() > 0 && posConf.getScreenHeight() > 0) {
199
                            f.setSize(new Dimension(POSConfiguration.getInstance().getScreenWidth() - f.getX(), POSConfiguration.getInstance().getScreenHeight() - f.getY()));
245
                            f.setSize(new Dimension(posConf.getScreenWidth() - f.getX(), posConf.getScreenHeight() - f.getY()));
200
                        } else {
246
                        } else {
201
                            f.setSize(new Dimension(screenSize.getSize().width - f.getX(), screenSize.getSize().height - f.getY()));
247
                            f.setSize(new Dimension(screenSize.getSize().width - f.getX(), screenSize.getSize().height - f.getY()));
202
                        }
248
                        }
203
                        System.out.println("Affichage de l'interface");
249
                        System.out.println("Affichage de l'interface");
204
                        f.setVisible(true);
250
                        f.setVisible(true);
Line 217... Line 263...
217
            // Catch throwable to be able to see NoClassDefFound and other hard issues
263
            // Catch throwable to be able to see NoClassDefFound and other hard issues
218
            ExceptionHandler.handle("Erreur d'initialisation de la caisse", e);
264
            ExceptionHandler.handle("Erreur d'initialisation de la caisse", e);
219
        }
265
        }
220
    }
266
    }
221
 
267
 
-
 
268
    public static class ReconcileException extends IllegalStateException {
-
 
269
        private RegisterState localState, remoteState;
-
 
270
        private final String translationKey;
-
 
271
 
-
 
272
        protected ReconcileException(final String msg, final String key) {
-
 
273
            this(msg, key, null);
-
 
274
        }
-
 
275
 
-
 
276
        protected ReconcileException(final String msg, final String key, final Throwable cause) {
-
 
277
            super(Objects.requireNonNull(msg, "message"), cause);
-
 
278
            this.translationKey = Objects.requireNonNull(key, "translation key");
-
 
279
        }
-
 
280
 
-
 
281
        public final RegisterState getLocalState() {
-
 
282
            return this.localState;
-
 
283
        }
-
 
284
 
-
 
285
        public final RegisterState getRemoteState() {
-
 
286
            return this.remoteState;
-
 
287
        }
-
 
288
 
-
 
289
        public final String getTranslationKey() {
-
 
290
            return this.translationKey;
-
 
291
        }
-
 
292
 
-
 
293
        protected final ReconcileException init(final RegisterState localState, final RegisterState remoteState) {
-
 
294
            this.localState = Objects.requireNonNull(localState, "local state");
-
 
295
            this.remoteState = Objects.requireNonNull(remoteState, "remote state");
-
 
296
            return this;
-
 
297
        }
-
 
298
    }
-
 
299
 
-
 
300
    // the FS and/or DB states were modified outside of this software.
-
 
301
    public static final class OutsideMeddlingException extends ReconcileException {
-
 
302
        protected OutsideMeddlingException(final String msg, final String key) {
-
 
303
            super(msg, key);
-
 
304
        }
-
 
305
    }
-
 
306
 
-
 
307
    // the opening or closure was interrupted, the process was resumed but it failed.
-
 
308
    public static final class ResumeException extends ReconcileException {
-
 
309
        protected ResumeException(final String msg, final String key, final Throwable cause) {
-
 
310
            super(msg, key, Objects.requireNonNull(cause, "missing cause"));
-
 
311
        }
-
 
312
    }
-
 
313
 
-
 
314
    /*
-
 
315
     * List of translations keys.
-
 
316
     */
-
 
317
    private static final String unknownTK = "unknown";
-
 
318
    // localOpen
-
 
319
    private static final String open_datesMismatch = "open.datesMismatch";
-
 
320
    private static final String localOpen_remoteClosed = "localOpen_remoteClosed";
-
 
321
    private static final String localOpen_remoteMissing = "localOpen_remoteMissing";
-
 
322
    // remoteOpen
-
 
323
    private static final String localMissing_remoteReopen = "localMissing_remoteReopen";
-
 
324
    private static final String localOpenFailed_remoteOpen = "localOpenFailed_remoteOpen";
-
 
325
    private static final String localClosed_remoteCloseFailed = "localClosed_remoteCloseFailed";
-
 
326
    private static final String localClosed_remoteOpen_datesMismatch = "localClosed_remoteOpen.datesMismatch";
-
 
327
    // both closed
-
 
328
    private static final String localMissing_remoteClosed = "localMissing_remoteClosed";
-
 
329
    private static final String closed_datesMismatch = "closed.datesMismatch";
-
 
330
    private static final String localClosed_remoteMissing = "localClosed_remoteMissing";
-
 
331
 
222
    private static RegisterState reconcileFSandDB(final SQLElementDirectory dir, final RegisterFiles files, final RegisterDB registerDB, final int userID)
332
    private static RegisterState reconcileFSandDB(final POSConfiguration posConf, final SQLElementDirectory dir, final RegisterFiles files, final RegisterDB registerDB)
223
            throws IOException, JDOMException, ParseException, SQLException {
333
            throws IOException, JDOMException, ParseException, SQLException {
224
 
334
 
225
        // *** find local and remote states
335
        // *** find local and remote states
226
        final RegisterLog lastLog = files.getLastLog();
336
        final RegisterLog lastLog = files.getLastLog();
227
        POSConfiguration.getLogger().log(Level.CONFIG, "Found last log {0}", lastLog);
337
        POSConfiguration.getLogger().log(Level.CONFIG, "Found last log {0}", lastLog);
Line 241... Line 351...
241
 
351
 
242
        // *** import remaining obsolete receipts
352
        // *** import remaining obsolete receipts
243
        if (localState.getStatus() == Status.OBSOLETE) {
353
        if (localState.getStatus() == Status.OBSOLETE) {
244
            if (remoteState.hasDate())
354
            if (remoteState.hasDate())
245
                throw new IllegalStateException("There remains obsolete receipts but DB can no longer import them : " + remoteState);
355
                throw new IllegalStateException("There remains obsolete receipts but DB can no longer import them : " + remoteState);
246
            final List<Ticket> allTickets = POSConfiguration.getInstance().allTickets();
356
            final List<Ticket> allTickets = posConf.allTickets();
247
            POSConfiguration.getLogger().log(Level.INFO, "{0} obsolete receipt(s) will be stored in the DB", allTickets.size());
357
            POSConfiguration.getLogger().log(Level.INFO, "{0} obsolete receipt(s) will be stored in the DB", allTickets.size());
248
            POSConfiguration.getInstance().commitAll(allTickets);
358
            posConf.commitAll(allTickets);
249
            final List<File> remainingReceipts = ReceiptCode.getReceiptsToImport(files.getPosID());
359
            final List<File> remainingReceipts = ReceiptCode.getReceiptsToImport(files.getPosID());
250
            if (!remainingReceipts.isEmpty())
360
            if (!remainingReceipts.isEmpty())
251
                throw new IllegalStateException("Not all obsolete receipts could be imported : " + remainingReceipts);
361
                throw new IllegalStateException("Not all obsolete receipts could be imported : " + remainingReceipts);
252
            localState = new RegisterState(Status.CLOSED, null);
362
            localState = new RegisterState(Status.CLOSED, null);
253
            POSConfiguration.getLogger().log(Level.FINE, "All obsolete receipts have been stored in the DB");
363
            POSConfiguration.getLogger().log(Level.FINE, "All obsolete receipts have been stored in the DB");
Line 259... Line 369...
259
            throw new IllegalStateException("Unexpected remote status :" + remoteState);
369
            throw new IllegalStateException("Unexpected remote status :" + remoteState);
260
 
370
 
261
        // *** reconcile if possible
371
        // *** reconcile if possible
262
        if (!localState.equals(remoteState)) {
372
        if (!localState.equals(remoteState)) {
263
            POSConfiguration.getLogger().log(Level.INFO, "Different FS and DB state, will try to reconcile\nFS " + localState + " with\nDB " + remoteState);
373
            POSConfiguration.getLogger().log(Level.INFO, "Different FS and DB state, will try to reconcile\nFS " + localState + " with\nDB " + remoteState);
-
 
374
            final int userID = posConf.getUserID();
264
 
375
 
265
            // OK because of the check above
376
            // OK because of the check above
266
            final boolean localOpen = localState.getStatus() == Status.OPEN;
377
            final boolean localOpen = localState.getStatus() == Status.OPEN;
267
            final boolean remoteOpen = remoteState.getStatus() == Status.OPEN;
378
            final boolean remoteOpen = remoteState.getStatus() == Status.OPEN;
268
            // Time line
379
            // Time line
Line 282... Line 393...
282
            // Open Local
393
            // Open Local
283
            // 7
394
            // 7
284
            try {
395
            try {
285
                if (localOpen) {
396
                if (localOpen) {
286
                    if (remoteOpen) {
397
                    if (remoteOpen) {
287
                        throw new IllegalStateException("Both open with but with different dates");
398
                        throw new OutsideMeddlingException("Both open with but with different dates", open_datesMismatch);
288
                    } else {
399
                    } else {
289
                        // DB is at 0 or 5, local is at 2
400
                        // DB is at 0 or 5, local is at 2
290
                        throw new IllegalStateException("local is open but the DB isn't");
401
                        throw new OutsideMeddlingException("local is open but the DB isn't", remoteState.hasDate() ? localOpen_remoteClosed : localOpen_remoteMissing);
291
                    }
402
                    }
292
                } else if (remoteOpen) {
403
                } else if (remoteOpen) {
293
                    assert remoteState.hasDate() : "Remote state open without date : " + remoteState;
404
                    assert remoteState.hasDate() : "Remote state open without date : " + remoteState;
294
                    final SQLRowValues lastClosure = fetchedState.getLastClosureEntry();
405
                    final SQLRowValues lastClosure = fetchedState.getLastClosureEntry();
295
                    final java.util.Date lastClosureDate = lastClosure == null ? null : lastClosure.getDate("DATE").getTime();
406
                    final java.util.Date lastClosureDate = lastClosure == null ? null : lastClosure.getDate("DATE").getTime();
296
                    if (!localState.hasDate()) {
407
                    if (!localState.hasDate()) {
297
                        // at 1
408
                        // at 1
298
                        // MAYBE allow it for new install, for now the receipts must be copied
409
                        // MAYBE allow it for new install, for now the receipts must be copied
299
                        // over
410
                        // over
300
                        if (lastClosureDate != null)
411
                        if (lastClosureDate != null)
301
                            throw new IllegalStateException("DB was closed (" + lastClosureDate + ") and now open, but local log is missing");
412
                            throw new OutsideMeddlingException("DB was closed and now open, but local log is missing", localMissing_remoteReopen);
302
                        try {
413
                        try {
303
                            localState = files.open(userID, fetchedState).getRegisterState();
414
                            localState = files.open(userID, fetchedState).getRegisterState();
304
                        } catch (Exception e) {
415
                        } catch (Exception e) {
305
                            throw new IllegalStateException("The local opening (following the already open DB) failed", e);
416
                            throw new ResumeException("The local opening (following the already open DB) failed", localOpenFailed_remoteOpen, e);
306
                        }
417
                        }
307
                    } else if (remoteState.compareDateTo(lastLog.getFirstRegisterEvent().getDate()) == 0) {
418
                    } else if (remoteState.compareDateTo(lastLog.getFirstRegisterEvent().getDate()) == 0) {
308
                        // at 4
419
                        // at 4
309
                        try {
420
                        try {
310
                            remoteState = registerDB.close(userID, files.getLastLog()).getRegisterState();
421
                            remoteState = registerDB.close(posConf, files.getLastLog()).getRegisterState();
311
                        } catch (Exception e) {
422
                        } catch (Exception e) {
312
                            throw new IllegalStateException("The closure of the DB (following the already closed local) failed", e);
423
                            throw new ResumeException("The closure of the DB (following the already closed local) failed", localClosed_remoteCloseFailed, e);
313
                        }
424
                        }
314
                    } else if (lastClosureDate != null && localState.compareDateTo(lastClosureDate) == 0) {
425
                    } else if (lastClosureDate != null && localState.compareDateTo(lastClosureDate) == 0) {
315
                        // at 6, TODO factor with above
426
                        // at 6, TODO factor with above
316
                        try {
427
                        try {
317
                            localState = files.open(userID, fetchedState).getRegisterState();
428
                            localState = files.open(userID, fetchedState).getRegisterState();
318
                        } catch (Exception e) {
429
                        } catch (Exception e) {
319
                            throw new IllegalStateException("The local opening (following the already open DB) failed", e);
430
                            throw new ResumeException("The local opening (following the already open DB) failed", localOpenFailed_remoteOpen, e);
320
                        }
431
                        }
321
                    } else {
432
                    } else {
322
                        // DB is at 1, local is between 4 and 6
433
                        // DB is at 1, local is between 4 and 6
323
                        throw new IllegalStateException("DB was opened for a different date");
434
                        throw new OutsideMeddlingException("DB was opened for a different date", localClosed_remoteOpen_datesMismatch);
324
                    }
435
                    }
325
                } else {
436
                } else {
-
 
437
                    assert !localOpen && !remoteOpen;
326
                    if (!localState.hasDate()) {
438
                    if (!localState.hasDate()) {
327
                        assert remoteState.hasDate() : "Both closed with no dates, but not equal";
439
                        assert remoteState.hasDate() : "Both closed with no dates, but not equal";
328
                        // DB is at 5, local is at 0
440
                        // DB is at 5, local is at 0
329
                        // MAYBE allow it for new install, for now the receipts must be copied
441
                        // MAYBE allow it for new install, for now the receipts must be copied
330
                        // over
442
                        // over
331
                        throw new IllegalStateException("DB was opened and closed, but local log is missing");
443
                        throw new OutsideMeddlingException("DB was opened and closed, but local log is missing", localMissing_remoteClosed);
332
                    } else if (remoteState.hasDate()) {
444
                    } else if (remoteState.hasDate()) {
333
                        // DB is at 5, local is at 5 but not for the same day
445
                        // DB is at 5, local is at 5 but not for the same day
334
                        assert remoteState.compareDateTo(localState) != 0 : "Both closed with equal dates, but not equal";
446
                        assert remoteState.compareDateTo(localState) != 0 : "Both closed with equal dates, but not equal";
335
                        throw new IllegalStateException("DB was opened and closed for a different date");
447
                        throw new OutsideMeddlingException("DB was opened and closed for a different date", closed_datesMismatch);
336
                    } else {
448
                    } else {
337
                        // DB is at 0, local is between 4 and 6
449
                        // DB is at 0, local is between 4 and 6
338
                        throw new IllegalStateException("DB was never opened but local was closed");
450
                        throw new OutsideMeddlingException("DB was never opened but local was closed", localClosed_remoteMissing);
339
                    }
451
                    }
340
                }
452
                }
-
 
453
            } catch (ReconcileException e) {
-
 
454
                throw e.init(localState, remoteState);
341
            } catch (Exception e) {
455
            } catch (Exception e) {
342
                throw new IllegalStateException("States couldn't be reconciled, local : " + localState + ", remote : " + remoteState, e);
456
                throw new ReconcileException("Unknown exception", unknownTK, e).init(localState, remoteState);
343
            }
457
            }
344
        }
458
        }
345
        if (!remoteState.equals(localState))
459
        if (!remoteState.equals(localState))
346
            throw new IllegalStateException("Unexpected state");
460
            throw new IllegalStateException("Unexpected state");
347
        return remoteState;
461
        return remoteState;
348
    }
462
    }
349
 
463
 
350
    static public void quit() {
464
    static public void quit(final POSConfiguration posConf) {
351
        POSConfiguration.getLogger().log(Level.INFO, "User exit");
465
        POSConfiguration.getLogger().log(Level.INFO, "User exit");
352
        POSConfiguration.getInstance().closeConnexion();
466
        posConf.closeConnexion();
353
        Frame[] l = Frame.getFrames();
467
        Frame[] l = Frame.getFrames();
354
        for (int i = 0; i < l.length; i++) {
468
        for (int i = 0; i < l.length; i++) {
355
            Frame f = l[i];
469
            Frame f = l[i];
356
            System.err.println(f.getName() + " " + f + " Displayable: " + f.isDisplayable() + " Valid: " + f.isValid() + " Active: " + f.isActive());
470
            System.err.println(f.getName() + " " + f + " Displayable: " + f.isDisplayable() + " Valid: " + f.isValid() + " Active: " + f.isActive());
357
        }
471
        }
Line 363... Line 477...
363
        }
477
        }
364
    }
478
    }
365
 
479
 
366
    @Override
480
    @Override
367
    public void dispose() {
481
    public void dispose() {
368
        quit();
482
        quit(this.posConf);
369
        // Fermeture
483
        // Fermeture
370
        this.getControler().setLCD("   CAISSE FERMEE    ", "", 0);
484
        this.getControler().setLCD("   CAISSE FERMEE    ", "", 0);
371
        super.dispose();
485
        super.dispose();
372
    }
486
    }
373
 
487