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 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 151 Rev 156
1
/*
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 * 
3
 * 
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 * 
5
 * 
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
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
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
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.
9
 * language governing permissions and limitations under the License.
10
 * 
10
 * 
11
 * When distributing the software, include this License Header Notice in each file.
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
12
 */
13
 
13
 
14
 package org.openconcerto.erp.generationDoc;
14
 package org.openconcerto.erp.generationDoc;
15
 
15
 
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
17
import org.openconcerto.erp.core.common.ui.PreviewFrame;
17
import org.openconcerto.erp.core.common.ui.PreviewFrame;
-
 
18
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
-
 
19
import org.openconcerto.erp.core.sales.quote.report.PaypalStamper;
18
import org.openconcerto.erp.generationDoc.element.TypeModeleSQLElement;
20
import org.openconcerto.erp.generationDoc.element.TypeModeleSQLElement;
-
 
21
import org.openconcerto.erp.preferences.PayPalPreferencePanel;
19
import org.openconcerto.erp.storage.CloudStorageEngine;
22
import org.openconcerto.erp.storage.CloudStorageEngine;
20
import org.openconcerto.erp.storage.StorageEngine;
23
import org.openconcerto.erp.storage.StorageEngine;
21
import org.openconcerto.erp.storage.StorageEngines;
24
import org.openconcerto.erp.storage.StorageEngines;
22
import org.openconcerto.openoffice.OOUtils;
25
import org.openconcerto.openoffice.OOUtils;
23
import org.jopendocument.link.Component;
26
import org.jopendocument.link.Component;
24
import org.openconcerto.sql.Configuration;
27
import org.openconcerto.sql.Configuration;
25
import org.openconcerto.sql.element.SQLElement;
28
import org.openconcerto.sql.element.SQLElement;
26
import org.openconcerto.sql.model.SQLBase;
29
import org.openconcerto.sql.model.SQLBase;
27
import org.openconcerto.sql.model.SQLRow;
30
import org.openconcerto.sql.model.SQLRow;
28
import org.openconcerto.sql.model.SQLRowAccessor;
31
import org.openconcerto.sql.model.SQLRowAccessor;
-
 
32
import org.openconcerto.sql.preferences.SQLPreferences;
29
import org.openconcerto.utils.ExceptionHandler;
33
import org.openconcerto.utils.ExceptionHandler;
30
import org.openconcerto.utils.cc.ITransformer;
34
import org.openconcerto.utils.cc.ITransformer;
31
 
35
 
-
 
36
import java.awt.GraphicsEnvironment;
32
import java.awt.print.PrinterJob;
37
import java.awt.print.PrinterJob;
33
import java.io.BufferedInputStream;
38
import java.io.BufferedInputStream;
34
import java.io.File;
39
import java.io.File;
35
import java.io.FileInputStream;
40
import java.io.FileInputStream;
-
 
41
import java.io.FileNotFoundException;
36
import java.io.IOException;
42
import java.io.IOException;
-
 
43
import java.io.InputStream;
-
 
44
import java.io.InputStreamReader;
-
 
45
import java.io.OutputStream;
37
import java.lang.Thread.UncaughtExceptionHandler;
46
import java.lang.Thread.UncaughtExceptionHandler;
-
 
47
import java.net.HttpURLConnection;
-
 
48
import java.net.URL;
-
 
49
import java.net.URLConnection;
-
 
50
import java.net.URLEncoder;
-
 
51
import java.nio.charset.StandardCharsets;
38
import java.util.Arrays;
52
import java.util.Arrays;
39
import java.util.HashMap;
53
import java.util.HashMap;
40
import java.util.List;
54
import java.util.List;
41
import java.util.Map;
55
import java.util.Map;
-
 
56
import java.util.StringJoiner;
42
import java.util.concurrent.Callable;
57
import java.util.concurrent.Callable;
43
import java.util.concurrent.ExecutionException;
58
import java.util.concurrent.ExecutionException;
44
import java.util.concurrent.ExecutorService;
59
import java.util.concurrent.ExecutorService;
45
import java.util.concurrent.Future;
60
import java.util.concurrent.Future;
46
import java.util.concurrent.LinkedBlockingQueue;
61
import java.util.concurrent.LinkedBlockingQueue;
47
import java.util.concurrent.ThreadFactory;
62
import java.util.concurrent.ThreadFactory;
48
import java.util.concurrent.ThreadPoolExecutor;
63
import java.util.concurrent.ThreadPoolExecutor;
49
import java.util.concurrent.TimeUnit;
64
import java.util.concurrent.TimeUnit;
50
 
65
 
51
import javax.swing.JOptionPane;
66
import javax.swing.JOptionPane;
52
 
67
 
53
import org.jopendocument.model.OpenDocument;
68
import org.jopendocument.model.OpenDocument;
54
 
69
 
55
public abstract class SheetXml {
70
public abstract class SheetXml {
56
 
71
 
57
    private ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> postProcess = null;
72
    private ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> postProcess = null;
58
 
73
 
59
    public ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> getPostProcess() {
74
    public ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> getPostProcess() {
60
        return postProcess;
75
        return postProcess;
61
    }
76
    }
62
 
77
 
63
    // INSTEAD USE THE PREF IN L.O. CALC --> Formules, toujours recalculer
78
    // INSTEAD USE THE PREF IN L.O. CALC --> Formules, toujours recalculer
64
    private boolean refreshFormulasRequired = false;
79
    private boolean refreshFormulasRequired = false;
65
 
80
 
66
    // return null to keep default value
81
    // return null to keep default value
67
    public interface StorageDirs {
82
    public interface StorageDirs {
68
        public File getDocumentOutputDirectory(SheetXml sheet);
83
        public File getDocumentOutputDirectory(SheetXml sheet);
69
 
84
 
70
        public File getPDFOutputDirectory(SheetXml sheet);
85
        public File getPDFOutputDirectory(SheetXml sheet);
71
 
86
 
72
        public String getStoragePath(SheetXml sheet);
87
        public String getStoragePath(SheetXml sheet);
73
    }
88
    }
74
 
89
 
75
    /**
90
    /**
76
     * Post process line
91
     * Post process line
77
     * 
92
     * 
78
     * @param postProcess
93
     * @param postProcess
79
     */
94
     */
80
    public void setPostProcess(ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> postProcess) {
95
    public void setPostProcess(ITransformer<List<SQLRowAccessor>, List<SQLRowAccessor>> postProcess) {
81
        this.postProcess = postProcess;
96
        this.postProcess = postProcess;
82
    }
97
    }
83
 
98
 
84
    private static StorageDirs STORAGE_DIRS;
99
    private static StorageDirs STORAGE_DIRS;
85
 
100
 
86
    // allow to redirect all documents
101
    // allow to redirect all documents
87
    public static void setStorageDirs(StorageDirs d) {
102
    public static void setStorageDirs(StorageDirs d) {
88
        STORAGE_DIRS = d;
103
        STORAGE_DIRS = d;
89
    }
104
    }
90
 
105
 
91
    public static final String DEFAULT_PROPERTY_NAME = "Default";
106
    public static final String DEFAULT_PROPERTY_NAME = "Default";
92
    protected SQLElement elt;
107
    protected SQLElement elt;
93
 
108
 
94
    // nom de l'imprimante à utiliser
109
    // nom de l'imprimante à utiliser
95
    protected String printer;
110
    protected String printer;
96
 
111
 
97
    // id
112
    // id
98
    protected SQLRow row;
113
    protected SQLRow row;
99
 
114
 
100
    // Language du document
115
    // Language du document
101
    protected SQLRow rowLanguage;
116
    protected SQLRow rowLanguage;
102
 
117
 
103
    protected static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
118
    protected static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
104
 
119
 
105
    // single threaded and kill its thread after 3 seconds (to allow the program to exit)
120
    // single threaded and kill its thread after 3 seconds (to allow the program to exit)
106
    protected static final ExecutorService runnableQueue = new ThreadPoolExecutor(0, 1, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
121
    protected static final ExecutorService runnableQueue = new ThreadPoolExecutor(0, 1, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
107
 
122
 
108
        @Override
123
        @Override
109
        public Thread newThread(Runnable r) {
124
        public Thread newThread(Runnable r) {
110
            final Thread res = new Thread(r);
125
            final Thread res = new Thread(r);
111
            res.setUncaughtExceptionHandler(DEFAULT_HANDLER);
126
            res.setUncaughtExceptionHandler(DEFAULT_HANDLER);
112
 
127
 
113
            return res;
128
            return res;
114
        }
129
        }
115
    });
130
    });
116
 
131
 
117
    protected static UncaughtExceptionHandler DEFAULT_HANDLER = new UncaughtExceptionHandler() {
132
    protected static UncaughtExceptionHandler DEFAULT_HANDLER = new UncaughtExceptionHandler() {
118
        @Override
133
        @Override
119
        public void uncaughtException(Thread t, Throwable e) {
134
        public void uncaughtException(Thread t, Throwable e) {
120
            ExceptionHandler.handle("Erreur de generation", e);
135
            ExceptionHandler.handle("Erreur de generation", e);
121
        }
136
        }
122
    };
137
    };
123
 
138
 
124
    public final SQLElement getElement() {
139
    public final SQLElement getElement() {
125
        return this.elt;
140
        return this.elt;
126
    }
141
    }
127
 
142
 
128
    /**
143
    /**
129
     * Show, print and export the document to PDF. This method is asynchronous, but is executed in a
144
     * Show, print and export the document to PDF. This method is asynchronous, but is executed in a
130
     * single threaded queue shared with createDocument
145
     * single threaded queue shared with createDocument
131
     */
146
     */
132
    public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
147
    public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
133
        final Callable<SheetXml> c = new Callable<SheetXml>() {
148
        final Callable<SheetXml> c = new Callable<SheetXml>() {
134
            @Override
149
            @Override
135
            public SheetXml call() throws Exception {
150
            public SheetXml call() throws Exception {
136
                showPrintAndExport(showDocument, printDocument, exportToPDF);
151
                showPrintAndExport(showDocument, printDocument, exportToPDF);
137
                return SheetXml.this;
152
                return SheetXml.this;
138
            }
153
            }
139
        };
154
        };
140
        return runnableQueue.submit(c);
155
        return runnableQueue.submit(c);
141
 
156
 
142
    }
157
    }
143
 
158
 
144
    public static Future<?> submitInQueue(final Runnable r) {
159
    public static Future<?> submitInQueue(final Runnable r) {
145
 
160
 
146
        return runnableQueue.submit(r);
161
        return runnableQueue.submit(r);
147
    }
162
    }
148
 
163
 
149
    public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
164
    public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
150
        showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false);
165
        showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false);
151
    }
166
    }
152
 
167
 
153
    /**
168
    /**
154
     * Show, print and export the document to PDF. This method is synchronous
169
     * Show, print and export the document to PDF. This method is synchronous
155
     */
170
     */
156
    public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch) {
171
    public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch) {
157
 
172
 
158
        final File generatedFile = getGeneratedFile();
173
        final File generatedFile = getGeneratedFile();
159
        final File pdfFile = getGeneratedPDFFile();
174
        final File pdfFile = getGeneratedPDFFile();
160
        if (generatedFile == null || !generatedFile.exists()) {
175
        if (generatedFile == null || !generatedFile.exists()) {
161
            JOptionPane.showMessageDialog(null, "Fichier généré manquant : " + generatedFile);
176
            JOptionPane.showMessageDialog(null, "Fichier généré manquant : " + generatedFile);
162
            return;
177
            return;
163
        }
178
        }
164
 
179
 
165
        try {
180
        try {
166
            if (!useODSViewer) {
181
            if (!useODSViewer) {
167
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(generatedFile, !showDocument);
182
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(generatedFile, !showDocument);
168
 
183
 
169
                if (printDocument) {
184
                if (printDocument) {
170
                    Map<String, Object> map = new HashMap<String, Object>();
185
                    Map<String, Object> map = new HashMap<String, Object>();
171
                    map.put("Name", this.printer);
186
                    map.put("Name", this.printer);
172
                    doc.printDocument(map);
187
                    doc.printDocument(map);
173
                }
188
                }
174
                if (exportToPDF) {
189
                if (exportToPDF) {
175
                    doc.saveToPDF(pdfFile).get();
190
                    doc.saveToPDF(pdfFile).get();
176
                }
191
                }
177
                if (!showDocument) {
192
                if (!showDocument) {
178
                    doc.close();
193
                    doc.close();
179
                }
194
                }
180
            } else {
195
            } else {
181
                final OpenDocument doc = new OpenDocument(generatedFile);
196
                final OpenDocument doc = new OpenDocument(generatedFile);
182
 
197
 
183
                if (showDocument) {
198
                if (showDocument) {
184
                    showPreviewDocument();
199
                    showPreviewDocument();
185
                }
200
                }
186
                if (printDocument) {
201
                if (printDocument) {
187
                    // Print !
202
                    // Print !
188
                    DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
203
                    DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
189
                    printer.print(Arrays.asList(doc));
204
                    printer.print(Arrays.asList(doc));
190
                }
205
                }
191
 
206
 
192
                // FIXME Profiler pour utiliser moins de ram --> ex : demande trop de mémoire pour
207
                // FIXME Profiler pour utiliser moins de ram --> ex : demande trop de mémoire pour
193
                // faire
208
                // faire
194
                // un grand livre KD
209
                // un grand livre KD
195
                if (exportToPDF) {
210
                if (exportToPDF) {
196
 
211
 
197
                    Thread t = new Thread(new Runnable() {
212
                    Thread t = new Thread(new Runnable() {
198
 
213
 
199
                        @Override
214
                        @Override
200
                        public void run() {
215
                        public void run() {
201
                            createPDF(generatedFile, pdfFile, doc, getStoragePath());
216
                            createPDF(generatedFile, pdfFile, doc, getStoragePath());
202
 
217
 
203
                        }
218
                        }
204
 
219
 
205
                    }, "convert and upload to pdf");
220
                    }, "convert and upload to pdf");
206
 
221
 
207
                    t.setDaemon(true);
222
                    t.setDaemon(true);
208
                    t.start();
223
                    t.start();
209
                    if (exportPDFSynch) {
224
                    if (exportPDFSynch) {
210
                        t.join();
225
                        t.join();
211
                    }
226
                    }
212
                }
227
                }
213
            }
228
            }
214
 
229
 
215
        } catch (Exception e) {
230
        } catch (Exception e) {
216
            e.printStackTrace();
-
 
217
            ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
231
            ExceptionHandler.handle("Impossible de charger le document OpenOffice " + pdfFile.getAbsolutePath() + "(viewer : " + useODSViewer + ")", e);
218
        }
232
        }
219
    }
233
    }
220
 
234
 
221
    MetaDataSheet meta;
235
    MetaDataSheet meta;
222
 
236
 
223
    /**
237
    /**
224
     * MetaData à inclure lors de la génération
238
     * MetaData à inclure lors de la génération
225
     * 
239
     * 
226
     * @param meta
240
     * @param meta
227
     */
241
     */
228
    public void setMetaGeneration(MetaDataSheet meta) {
242
    public void setMetaGeneration(MetaDataSheet meta) {
229
        this.meta = meta;
243
        this.meta = meta;
230
    }
244
    }
231
 
245
 
232
    /**
246
    /**
233
     * MetaData à inclure lors de la génération
247
     * MetaData à inclure lors de la génération
234
     * 
248
     * 
235
     * @param meta
249
     * @param meta
236
     */
250
     */
237
 
251
 
238
    public MetaDataSheet getMetaGeneration() {
252
    public MetaDataSheet getMetaGeneration() {
239
        return this.meta;
253
        return this.meta;
240
    }
254
    }
241
 
255
 
242
    public static void createPDF(final File generatedFile, final File pdfFile, final OpenDocument doc, String storagePath) {
256
    public void createPDF(final File generatedFile, final File pdfFile, final OpenDocument doc, String storagePath) {
243
        if (pdfFile == null) {
257
        if (pdfFile == null) {
244
            throw new IllegalArgumentException("null PDF file");
258
            throw new IllegalArgumentException("null PDF file");
245
        }
259
        }
246
        try {
260
        try {
-
 
261
            if (VenteFactureXmlSheet.TEMPLATE_ID.equals(getDefaultTemplateId())) {
-
 
262
                final SQLPreferences prefs = SQLPreferences.getMemCached(getElement().getTable().getDBRoot());
-
 
263
                if (prefs.getBoolean(PayPalPreferencePanel.PAYPAL_INVOICE, false)) {
-
 
264
                    try {
-
 
265
                        final File inFile = File.createTempFile("oc_", pdfFile.getName());
-
 
266
                        SheetUtils.convert2PDF(doc, inFile);
-
 
267
                        PaypalStamper s = new PaypalStamper();
-
 
268
                        int x = prefs.getInt(PayPalPreferencePanel.PAYPAL_INVOICE_X, 0);
-
 
269
                        int y = prefs.getInt(PayPalPreferencePanel.PAYPAL_INVOICE_Y, 0);
-
 
270
 
-
 
271
                        // Reference
-
 
272
                        String ref = getSQLRow().getString("NUMERO");
-
 
273
                        // Montant : ex : 10.55
-
 
274
                        long cents = getSQLRow().getLong("NET_A_PAYER");
-
 
275
                        String amount = cents / 100 + "." + cents % 100;
-
 
276
                        // Devise
-
 
277
                        // TODO : autres devises
-
 
278
                        String currency = "EUR";
-
 
279
                        // POST
-
 
280
                        final URL url = new URL("https://cloud.openconcerto.org/payment");
-
 
281
                        final URLConnection con = url.openConnection();
-
 
282
                        final HttpURLConnection http = (HttpURLConnection) con;
-
 
283
                        http.setRequestMethod("POST");
-
 
284
                        http.setDoOutput(true);
-
 
285
                        http.setDefaultUseCaches(false);
-
 
286
 
-
 
287
                        String hyperlink = null;
-
 
288
                        // x-www-form-urlencoded
-
 
289
                        final Map<String, String> arguments = new HashMap<>();
-
 
290
                        arguments.put("pI", prefs.get(PayPalPreferencePanel.PAYPAL_CLIENTID, ""));
-
 
291
                        arguments.put("pS", prefs.get(PayPalPreferencePanel.PAYPAL_SECRET, ""));
-
 
292
                        arguments.put("ref", ref);
-
 
293
                        arguments.put("amount", amount);
-
 
294
                        arguments.put("currency", currency);
-
 
295
                        arguments.put("type", "paypal");
-
 
296
                        final StringJoiner sj = new StringJoiner("&");
-
 
297
                        for (Map.Entry<String, String> entry : arguments.entrySet()) {
-
 
298
                            sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8"));
-
 
299
                        }
-
 
300
                        final String postData = sj.toString();
-
 
301
                        System.err.println("SheetXml.createPDF() " + postData);
-
 
302
                        byte[] out = postData.getBytes(StandardCharsets.UTF_8);
-
 
303
                        int length = out.length;
-
 
304
                        http.setFixedLengthStreamingMode(length);
-
 
305
                        http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
-
 
306
                        http.connect();
-
 
307
                        try (OutputStream os = http.getOutputStream()) {
-
 
308
                            os.write(out);
-
 
309
                        }
-
 
310
                        if (http.getResponseCode() != 401) {
-
 
311
 
-
 
312
                            InputStream is = http.getInputStream();
-
 
313
                            InputStreamReader isr = new InputStreamReader(is);
-
 
314
 
-
 
315
                            int numCharsRead;
-
 
316
                            char[] charArray = new char[1024];
-
 
317
                            StringBuilder sb = new StringBuilder();
-
 
318
                            while ((numCharsRead = isr.read(charArray)) > 0) {
-
 
319
                                sb.append(charArray, 0, numCharsRead);
-
 
320
                            }
-
 
321
                            //
-
 
322
                            hyperlink = sb.toString();
-
 
323
                        }
-
 
324
                        s.addLink(inFile, pdfFile, x, y, hyperlink);
-
 
325
                    } catch (Exception e) {
-
 
326
                        e.printStackTrace();
247
            SheetUtils.convert2PDF(doc, pdfFile);
327
                        SheetUtils.convert2PDF(doc, pdfFile);
-
 
328
                    }
-
 
329
 
-
 
330
                } else {
-
 
331
                    SheetUtils.convert2PDF(doc, pdfFile);
-
 
332
                }
-
 
333
            } else {
-
 
334
                SheetUtils.convert2PDF(doc, pdfFile);
-
 
335
            }
-
 
336
 
248
        } catch (Throwable e) {
337
        } catch (Throwable e) {
249
            ExceptionHandler.handle("Impossible de créer le PDF " + pdfFile.getAbsolutePath(), e);
338
            ExceptionHandler.handle("Impossible de créer le PDF " + pdfFile.getAbsolutePath(), e);
250
        }
339
        }
251
        if (!pdfFile.canRead()) {
340
        if (!pdfFile.canRead()) {
252
            ExceptionHandler.handle("Le fichier PDF " + pdfFile.getAbsolutePath() + " ne peut être lu.");
341
            ExceptionHandler.handle("Le fichier PDF " + pdfFile.getAbsolutePath() + " ne peut être lu.");
253
        }
342
        }
254
        List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
343
        List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
255
        for (StorageEngine storageEngine : engines) {
344
        for (StorageEngine storageEngine : engines) {
256
            if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
345
            if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
257
                final String path = storagePath;
346
                final String path = storagePath;
258
                try {
347
                try {
259
                    storageEngine.connect();
348
                    storageEngine.connect();
260
                    final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(pdfFile));
349
                    final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(pdfFile));
261
                    storageEngine.store(inStream, path, pdfFile.getName(), true);
350
                    storageEngine.store(inStream, path, pdfFile.getName(), true);
262
                    inStream.close();
351
                    inStream.close();
263
                    storageEngine.disconnect();
352
                    storageEngine.disconnect();
264
                } catch (IOException e) {
353
                } catch (IOException e) {
265
                    ExceptionHandler.handle("Impossible de sauvegarder le PDF " + pdfFile.getAbsolutePath() + " vers " + path + "(" + storageEngine + ")", e);
354
                    ExceptionHandler.handle("Impossible de sauvegarder le PDF " + pdfFile.getAbsolutePath() + " vers " + path + "(" + storageEngine + ")", e);
266
                }
355
                }
267
                if (storageEngine instanceof CloudStorageEngine) {
356
                if (storageEngine instanceof CloudStorageEngine) {
268
                    try {
357
                    try {
269
                        storageEngine.connect();
358
                        storageEngine.connect();
270
                        final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(generatedFile));
359
                        final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(generatedFile));
271
                        storageEngine.store(inStream, path, generatedFile.getName(), true);
360
                        storageEngine.store(inStream, path, generatedFile.getName(), true);
272
                        inStream.close();
361
                        inStream.close();
273
                        storageEngine.disconnect();
362
                        storageEngine.disconnect();
274
                    } catch (IOException e) {
363
                    } catch (IOException e) {
275
                        ExceptionHandler.handle("Impossible de sauvegarder le fichier généré " + generatedFile.getAbsolutePath() + " vers " + path + "(" + storageEngine + ")", e);
364
                        ExceptionHandler.handle("Impossible de sauvegarder le fichier généré " + generatedFile.getAbsolutePath() + " vers " + path + "(" + storageEngine + ")", e);
276
                    }
365
                    }
277
                }
366
                }
278
            }
367
            }
279
        }
368
        }
280
    }
369
    }
281
 
370
 
282
    public abstract String getDefaultTemplateId();
371
    public abstract String getDefaultTemplateId();
283
 
372
 
284
    /**
373
    /**
285
     * Path of the directory used for storage. Ex: Devis/2010
374
     * Path of the directory used for storage. Ex: Devis/2010
286
     */
375
     */
287
    public final String getStoragePath() {
376
    public final String getStoragePath() {
288
        final String res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getStoragePath(this);
377
        final String res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getStoragePath(this);
289
        if (res != null)
378
        if (res != null)
290
            return res;
379
            return res;
291
        else
380
        else
292
            return this.getStoragePathP();
381
            return this.getStoragePathP();
293
    }
382
    }
294
 
383
 
295
    public final File getDocumentOutputDirectory() {
384
    public final File getDocumentOutputDirectory() {
296
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getDocumentOutputDirectory(this);
385
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getDocumentOutputDirectory(this);
297
        if (res != null)
386
        if (res != null)
298
            return res;
387
            return res;
299
        else
388
        else
300
            return this.getDocumentOutputDirectoryP();
389
            return this.getDocumentOutputDirectoryP();
301
    }
390
    }
302
 
391
 
303
    public final File getPDFOutputDirectory() {
392
    public final File getPDFOutputDirectory() {
304
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getPDFOutputDirectory(this);
393
        final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getPDFOutputDirectory(this);
305
        if (res != null)
394
        if (res != null)
306
            return res;
395
            return res;
307
        else
396
        else
308
            return this.getPDFOutputDirectoryP();
397
            return this.getPDFOutputDirectoryP();
309
    }
398
    }
310
 
399
 
311
    protected abstract String getStoragePathP();
400
    protected abstract String getStoragePathP();
312
 
401
 
313
    protected abstract File getDocumentOutputDirectoryP();
402
    protected abstract File getDocumentOutputDirectoryP();
314
 
403
 
315
    protected abstract File getPDFOutputDirectoryP();
404
    protected abstract File getPDFOutputDirectoryP();
316
 
405
 
317
    /**
406
    /**
318
     * Name of the generated document (without extension), do not rely on this name.
407
     * Name of the generated document (without extension), do not rely on this name.
319
     * 
408
     * 
320
     * Use getGeneratedFile().getName() to get the generated file name.
409
     * Use getGeneratedFile().getName() to get the generated file name.
321
     */
410
     */
322
    public abstract String getName();
411
    public abstract String getName();
323
 
412
 
324
    /**
413
    /**
325
     * @return the template id for this template (ex: "sales.quote")
414
     * @return the template id for this template (ex: "sales.quote")
326
     */
415
     */
327
    public String getTemplateId() {
416
    public String getTemplateId() {
328
        if (this.row != null && this.row.getTable().getFieldsName().contains("ID_MODELE")) {
417
        if (this.row != null && this.row.getTable().getFieldsName().contains("ID_MODELE")) {
329
            if (row.getObject("ID_MODELE") == null || row.isForeignEmpty("ID_MODELE")) {
418
            if (row.getObject("ID_MODELE") == null || row.isForeignEmpty("ID_MODELE")) {
330
                TypeModeleSQLElement typeModele = Configuration.getInstance().getDirectory().getElement(TypeModeleSQLElement.class);
419
                TypeModeleSQLElement typeModele = Configuration.getInstance().getDirectory().getElement(TypeModeleSQLElement.class);
331
                String modele = typeModele.getTemplateMapping().get(this.row.getTable().getName());
420
                String modele = typeModele.getTemplateMapping().get(this.row.getTable().getName());
332
                if (modele == null) {
421
                if (modele == null) {
333
                    System.err.println("No default modele in table TYPE_MODELE for table " + this.row.getTable().getName());
422
                    System.err.println("No default modele in table TYPE_MODELE for table " + this.row.getTable().getName());
334
                    Thread.dumpStack();
423
                    Thread.dumpStack();
335
                    return getDefaultTemplateId();
424
                    return getDefaultTemplateId();
336
                } else {
425
                } else {
337
                    return modele;
426
                    return modele;
338
                }
427
                }
339
            } else {
428
            } else {
340
                SQLRow rowModele = this.row.getForeignRow("ID_MODELE");
429
                SQLRow rowModele = this.row.getForeignRow("ID_MODELE");
341
                return rowModele.getString("NOM");
430
                return rowModele.getString("NOM");
342
            }
431
            }
343
        }
432
        }
344
        return getDefaultTemplateId();
433
        return getDefaultTemplateId();
345
    }
434
    }
346
 
435
 
347
    public abstract Future<SheetXml> createDocumentAsynchronous();
436
    public abstract Future<SheetXml> createDocumentAsynchronous();
348
 
437
 
349
    public void createDocument() throws InterruptedException, ExecutionException {
438
    public void createDocument() throws InterruptedException, ExecutionException {
350
        createDocumentAsynchronous().get();
439
        createDocumentAsynchronous().get();
351
    }
440
    }
352
 
441
 
353
    /**
442
    /**
354
     * get the File that is, or must be generated.
443
     * get the File that is, or must be generated.
355
     * 
444
     * 
356
     * @return a file (not null)
445
     * @return a file (not null)
357
     */
446
     */
358
    public abstract File getGeneratedFile();
447
    public abstract File getGeneratedFile();
359
 
448
 
360
    public File getGeneratedPDFFile() {
449
    public File getGeneratedPDFFile() {
361
        return SheetUtils.getFileWithExtension(getGeneratedFile(), ".pdf");
450
        return SheetUtils.getFileWithExtension(getGeneratedFile(), ".pdf");
362
    }
451
    }
363
 
452
 
364
    public SQLRow getRowLanguage() {
453
    public SQLRow getRowLanguage() {
365
        return this.rowLanguage;
454
        return this.rowLanguage;
366
    }
455
    }
367
 
456
 
368
    public String getReference() {
457
    public String getReference() {
369
        return "";
458
        return "";
370
    }
459
    }
371
 
460
 
372
    /**
461
    /**
373
     * Creates the document if needed and returns the generated file (OpenDocument)
462
     * Creates the document if needed and returns the generated file (OpenDocument)
374
     */
463
     */
375
    public File getOrCreateDocumentFile() throws Exception {
464
    public File getOrCreateDocumentFile() throws Exception {
376
        File f = getGeneratedFile();
465
        File f = getGeneratedFile();
377
        if (!f.exists()) {
466
        if (!f.exists()) {
378
            return createDocumentAsynchronous().get().getGeneratedFile();
467
            return createDocumentAsynchronous().get().getGeneratedFile();
379
        } else {
468
        } else {
380
            return f;
469
            return f;
381
        }
470
        }
382
    }
471
    }
383
 
472
 
384
    /**
473
    /**
385
     * Creates the document if needed and returns the generated file (OpenDocument)
474
     * Creates the document if needed and returns the generated file (OpenDocument)
386
     * 
475
     * 
387
     * @param createRecent true for recreate the pdf document if older than ods
476
     * @param createRecent true for recreate the pdf document if older than ods
388
     * @return
477
     * @return
389
     * @throws Exception
478
     * @throws Exception
390
     * 
479
     * 
391
     */
480
     */
392
    public File getOrCreatePDFDocumentFile(boolean createRecent) throws Exception {
481
    public File getOrCreatePDFDocumentFile(boolean createRecent) throws Exception {
393
        return getOrCreatePDFDocumentFile(createRecent, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"));
482
        return getOrCreatePDFDocumentFile(createRecent, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"));
394
    }
483
    }
395
 
484
 
396
    public File getOrCreatePDFDocumentFile(boolean createRecent, boolean useODSViewer) throws Exception {
485
    public File getOrCreatePDFDocumentFile(boolean createRecent, boolean useODSViewer) throws Exception {
397
        File f = getGeneratedPDFFile();
486
        File f = getGeneratedPDFFile();
398
        if (!f.exists()) {
487
        if (!f.exists()) {
399
            getOrCreateDocumentFile();
488
            getOrCreateDocumentFile();
400
            showPrintAndExport(false, false, true, useODSViewer, true);
489
            showPrintAndExport(false, false, true, useODSViewer, true);
401
            return f;
490
            return f;
402
        } else {
491
        } else {
403
            File fODS = getOrCreateDocumentFile();
492
            File fODS = getOrCreateDocumentFile();
404
            if (fODS.lastModified() > f.lastModified()) {
493
            if (fODS.lastModified() > f.lastModified()) {
405
                showPrintAndExport(false, false, true, useODSViewer, true);
494
                showPrintAndExport(false, false, true, useODSViewer, true);
406
            }
495
            }
407
            return f;
496
            return f;
408
        }
497
        }
409
    }
498
    }
410
 
499
 
411
    /**
500
    /**
412
     * Open the document with the native application
501
     * Open the document with the native application
413
     * 
502
     * 
414
     * @param synchronous
503
     * @param synchronous
415
     */
504
     */
416
    public void openDocument(boolean synchronous) {
505
    public void openDocument(boolean synchronous) {
417
        Runnable r = new Runnable() {
506
        Runnable r = new Runnable() {
418
 
507
 
419
            @Override
508
            @Override
420
            public void run() {
509
            public void run() {
421
                File f;
510
                File f;
422
                try {
511
                try {
423
                    f = getOrCreateDocumentFile();
512
                    f = getOrCreateDocumentFile();
424
                    // ComptaPropsConfiguration.getOOConnexion().loadDocument(f, false);
513
                    if (f != null && f.exists()) {
425
                    OOUtils.open(f);
514
                        OOUtils.open(f);
-
 
515
                    } else {
-
 
516
                        if (!GraphicsEnvironment.isHeadless()) {
-
 
517
                            if (f != null) {
-
 
518
                                JOptionPane.showMessageDialog(null, "Le fichier " + f.getAbsolutePath() + " est manquant");
-
 
519
                            } else {
-
 
520
                                JOptionPane.showMessageDialog(null, "Fichier manquant");
-
 
521
                            }
-
 
522
                        } else {
-
 
523
                            if (f != null) {
-
 
524
                                throw new FileNotFoundException(f.getAbsolutePath() + " missing");
-
 
525
                            } else {
-
 
526
                                throw new NullPointerException("null document");
-
 
527
                            }
-
 
528
                        }
-
 
529
                    }
426
                } catch (Exception e) {
530
                } catch (Exception e) {
427
                    ExceptionHandler.handle("Impossible d'ouvrir le document.", e);
531
                    ExceptionHandler.handle("Impossible d'ouvrir le document.", e);
428
                }
532
                }
429
            }
533
            }
430
        };
534
        };
431
        if (synchronous) {
535
        if (synchronous) {
432
            r.run();
536
            r.run();
433
        } else {
537
        } else {
434
            Thread thread = new Thread(r, "openDocument: " + getGeneratedFile().getAbsolutePath());
538
            Thread thread = new Thread(r, "openDocument: " + getGeneratedFile().getAbsolutePath());
435
            thread.setDaemon(true);
539
            thread.setDaemon(true);
436
            thread.start();
540
            thread.start();
437
        }
541
        }
438
 
542
 
439
    }
543
    }
440
 
544
 
441
    public void showPreviewDocument() throws Exception {
545
    public void showPreviewDocument() throws Exception {
442
        File f = null;
546
        File f = null;
443
        f = getOrCreateDocumentFile();
547
        f = getOrCreateDocumentFile();
444
        PreviewFrame.show(f);
548
        PreviewFrame.show(f);
445
    }
549
    }
446
 
550
 
447
    public void printDocument() {
551
    public void printDocument() {
448
        printDocument(null);
552
        printDocument(null);
449
    }
553
    }
450
 
554
 
451
    public void printDocument(PrinterJob job) {
555
    public void printDocument(PrinterJob job) {
452
 
556
 
453
        try {
557
        try {
454
            final File f = getOrCreateDocumentFile();
558
            final File f = getOrCreateDocumentFile();
455
 
559
 
456
            if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
560
            if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
457
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, true);
561
                final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, true);
458
                doc.printDocument(job);
562
                doc.printDocument(job);
459
                doc.close();
563
                doc.close();
460
            } else {
564
            } else {
461
                // Load the spreadsheet.
565
                // Load the spreadsheet.
462
                final OpenDocument doc = new OpenDocument(f);
566
                final OpenDocument doc = new OpenDocument(f);
463
                // Print !
567
                // Print !
464
                DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
568
                DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
465
                printer.print(Arrays.asList(doc), job);
569
                printer.print(Arrays.asList(doc), job);
466
            }
570
            }
467
 
571
 
468
        } catch (Exception e) {
572
        } catch (Exception e) {
469
            ExceptionHandler.handle("Impossible d'imprimer le document OpenOffice", e);
573
            ExceptionHandler.handle("Impossible d'imprimer le document OpenOffice", e);
470
            e.printStackTrace();
574
            e.printStackTrace();
471
        }
575
        }
472
    }
576
    }
473
 
577
 
474
    public SQLRow getSQLRow() {
578
    public SQLRow getSQLRow() {
475
        return this.row;
579
        return this.row;
476
    }
580
    }
477
 
581
 
478
    /**
582
    /**
479
     * Remplace tous les caracteres non alphanumeriques (seul le _ est autorisé) par un -. Cela
583
     * Remplace tous les caracteres non alphanumeriques (seul le _ est autorisé) par un -. Cela
480
     * permet d'avoir toujours un nom de fichier valide.
584
     * permet d'avoir toujours un nom de fichier valide.
481
     * 
585
     * 
482
     * @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
586
     * @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
483
     * @return un nom fichier valide ex:FACTURE_2007-03-001
587
     * @return un nom fichier valide ex:FACTURE_2007-03-001
484
     */
588
     */
485
    public static String getValidFileName(String fileName) {
589
    public static String getValidFileName(String fileName) {
486
        final StringBuffer result = new StringBuffer(fileName.length());
590
        final StringBuffer result = new StringBuffer(fileName.length());
487
        for (int i = 0; i < fileName.length(); i++) {
591
        for (int i = 0; i < fileName.length(); i++) {
488
            char ch = fileName.charAt(i);
592
            char ch = fileName.charAt(i);
489
 
593
 
490
            // Si c'est un caractere alphanumerique
594
            // Si c'est un caractere alphanumerique
491
            if (Character.isLetterOrDigit(ch) || (ch == '_') || (ch == ' ')) {
595
            if (Character.isLetterOrDigit(ch) || (ch == '_') || (ch == ' ')) {
492
                result.append(ch);
596
                result.append(ch);
493
            } else {
597
            } else {
494
                result.append('-');
598
                result.append('-');
495
            }
599
            }
496
        }
600
        }
497
        return result.toString();
601
        return result.toString();
498
    }
602
    }
499
 
603
 
500
    public String getPrinter() {
604
    public String getPrinter() {
501
        return this.printer;
605
        return this.printer;
502
    }
606
    }
503
 
607
 
504
    public void setRefreshFormulasRequired(boolean refreshFormulasRequired) {
608
    public void setRefreshFormulasRequired(boolean refreshFormulasRequired) {
505
        this.refreshFormulasRequired = refreshFormulasRequired;
609
        this.refreshFormulasRequired = refreshFormulasRequired;
506
    }
610
    }
507
 
611
 
508
    public boolean isRefreshFormulasRequired() {
612
    public boolean isRefreshFormulasRequired() {
509
            return refreshFormulasRequired;
613
            return refreshFormulasRequired;
510
    }
614
    }
511
 
615
 
512
}
616
}