AccountancyExport::exportSAGE50SWISS()   F
last analyzed

Complexity

Conditions 24
Paths 3074

Size

Total Lines 143
Code Lines 95

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 95
nc 3074
nop 2
dl 0
loc 143
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * Copyright (C) 2007-2012  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2014       Juanjo Menent               <[email protected]>
6
 * Copyright (C) 2015       Florian Henry               <[email protected]>
7
 * Copyright (C) 2015       Raphaël Doursenaud          <[email protected]>
8
 * Copyright (C) 2016       Pierre-Henry Favre          <[email protected]>
9
 * Copyright (C) 2016-2024  Alexandre Spangaro          <[email protected]>
10
 * Copyright (C) 2022  		Lionel Vessiller            <[email protected]>
11
 * Copyright (C) 2013-2017  Olivier Geffroy             <[email protected]>
12
 * Copyright (C) 2017       Elarifr. Ari Elbaz          <[email protected]>
13
 * Copyright (C) 2017-2019  Frédéric France             <[email protected]>
14
 * Copyright (C) 2017       André Schild                <[email protected]>
15
 * Copyright (C) 2020       Guillaume Alexandre         <[email protected]>
16
 * Copyright (C) 2022		Joachim Kueter		        <[email protected]>
17
 * Copyright (C) 2022  		Progiseize         	        <[email protected]>
18
 * Copyright (C) 2024		MDW							<[email protected]>
19
 * Copyright (C) 2024       Rafael San José             <[email protected]>
20
 *
21
 * This program is free software; you can redistribute it and/or modify
22
 * it under the terms of the GNU General Public License as published by
23
 * the Free Software Foundation; either version 3 of the License, or
24
 * (at your option) any later version.
25
 *
26
 * This program is distributed in the hope that it will be useful,
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29
 * GNU General Public License for more details.
30
 *
31
 * You should have received a copy of the GNU General Public License
32
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
33
 */
34
35
namespace Dolibarr\Code\Accountancy\Classes;
36
37
use DoliDB;
38
39
/**
40
 * \file        htdocs/accountancy/class/accountancyexport.class.php
41
 * \ingroup     Accountancy (Double entries)
42
 * \brief       Class accountancy export
43
 */
44
45
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions.lib.php';
46
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions2.lib.php';
47
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
48
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/accounting.lib.php';
49
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
50
51
/**
52
 * Manage the different format accountancy export
53
 */
54
class AccountancyExport
55
{
56
    // Types of export.
57
    public static $EXPORT_TYPE_CONFIGURABLE = 1; // CSV
58
    public static $EXPORT_TYPE_AGIRIS = 10;
59
    public static $EXPORT_TYPE_EBP = 15;
60
    public static $EXPORT_TYPE_CEGID = 20;
61
    public static $EXPORT_TYPE_COGILOG = 25;
62
    public static $EXPORT_TYPE_COALA = 30;
63
    public static $EXPORT_TYPE_BOB50 = 35;
64
    public static $EXPORT_TYPE_CIEL = 40;
65
    public static $EXPORT_TYPE_SAGE50_SWISS = 45;
66
    public static $EXPORT_TYPE_CHARLEMAGNE = 50;
67
    public static $EXPORT_TYPE_QUADRATUS = 60;
68
    public static $EXPORT_TYPE_WINFIC = 70;
69
    public static $EXPORT_TYPE_OPENCONCERTO = 100;
70
    public static $EXPORT_TYPE_LDCOMPTA = 110;
71
    public static $EXPORT_TYPE_LDCOMPTA10 = 120;
72
    public static $EXPORT_TYPE_GESTIMUMV3 = 130;
73
    public static $EXPORT_TYPE_GESTIMUMV5 = 135;
74
    public static $EXPORT_TYPE_ISUITEEXPERT = 200;
75
    // Generic FEC after that
76
    public static $EXPORT_TYPE_FEC = 1000;
77
    public static $EXPORT_TYPE_FEC2 = 1010;
78
79
    /**
80
     * @var DoliDB  Database handler
81
     */
82
    public $db;
83
84
    /**
85
     * @var string[] Error codes (or messages)
86
     */
87
    public $errors = array();
88
89
    /**
90
     * @var string  Separator
91
     */
92
    public $separator = '';
93
94
    /**
95
     * @var string  End of line
96
     */
97
    public $end_line = '';
98
99
    /**
100
     * @var array   Generated file
101
     */
102
    public $generatedfiledata = array();
103
104
105
    /**
106
     * Constructor
107
     *
108
     * @param DoliDB $db Database handler
109
     */
110
    public function __construct(DoliDB $db)
111
    {
112
        global $conf, $hookmanager;
113
114
        $this->db = $db;
115
        $this->separator = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
116
        $this->end_line = getDolGlobalString('ACCOUNTING_EXPORT_ENDLINE') ? (getDolGlobalInt('ACCOUNTING_EXPORT_ENDLINE') == 1 ? "\n" : "\r\n") : "\n";
117
118
        $hookmanager->initHooks(array('accountancyexport'));
119
    }
120
121
    /**
122
     * Array with all export type available (key + label)
123
     *
124
     * @param   int     $mode       Mode of list: 0=flat list, 1=rich list
125
     * @return                      array of type
126
     */
127
    public function getType($mode = 0)
128
    {
129
        global $langs, $hookmanager;
130
131
        $listofspecialformatexport = array(
132
            self::$EXPORT_TYPE_CEGID => $langs->trans('Modelcsv_CEGID'),
133
            self::$EXPORT_TYPE_COALA => $langs->trans('Modelcsv_COALA'),
134
            self::$EXPORT_TYPE_BOB50 => $langs->trans('Modelcsv_bob50'),
135
            self::$EXPORT_TYPE_CIEL => $langs->trans('Modelcsv_ciel'),
136
            self::$EXPORT_TYPE_QUADRATUS => $langs->trans('Modelcsv_quadratus'),
137
            self::$EXPORT_TYPE_WINFIC => $langs->trans('Modelcsv_winfic'),
138
            self::$EXPORT_TYPE_EBP => $langs->trans('Modelcsv_ebp'),
139
            self::$EXPORT_TYPE_COGILOG => $langs->trans('Modelcsv_cogilog'),
140
            self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris'),
141
            self::$EXPORT_TYPE_OPENCONCERTO => $langs->trans('Modelcsv_openconcerto'),
142
            self::$EXPORT_TYPE_SAGE50_SWISS => $langs->trans('Modelcsv_Sage50_Swiss'),
143
            self::$EXPORT_TYPE_CHARLEMAGNE => $langs->trans('Modelcsv_charlemagne'),
144
            self::$EXPORT_TYPE_LDCOMPTA => $langs->trans('Modelcsv_LDCompta'),
145
            self::$EXPORT_TYPE_LDCOMPTA10 => $langs->trans('Modelcsv_LDCompta10'),
146
            self::$EXPORT_TYPE_GESTIMUMV3 => $langs->trans('Modelcsv_Gestinumv3'),
147
            self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinumv5'),
148
            self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert',
149
        );
150
151
        $listofgenericformatexport = array(
152
            self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
153
            self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'),
154
            self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'),
155
        );
156
157
        if (empty($mode)) {
158
            $listofexporttypes = $listofgenericformatexport + $listofspecialformatexport;
159
            ksort($listofexporttypes, SORT_NUMERIC);
160
        } else {
161
            ksort($listofspecialformatexport, SORT_NUMERIC);
162
            $listofexporttypes = array();
163
            $i = 0;
164
            foreach ($listofgenericformatexport as $key => $val) {
165
                $i++;
166
                $listofexporttypes[$key] = array('id' => $key, 'label' => $val, 'position' => $i);
167
            }
168
            $listofexporttypes['separator_' . $i] = array('id' => 0, 'label' => '----------------', 'position' => $i, 'disabled' => 'disabled');
169
            foreach ($listofspecialformatexport as $key => $val) {
170
                $i++;
171
                $listofexporttypes[$key] = array('id' => $key, 'label' => $val, 'position' => $i);
172
            }
173
        }
174
175
        // allow modules to define export formats
176
        $parameters = array();
177
        $reshook = $hookmanager->executeHooks('getType', $parameters, $listofexporttypes);
178
179
        return $listofexporttypes;
180
    }
181
182
    /**
183
     * Return string to summarize the format (Used to generated export filename)
184
     *
185
     * @param   int     $type       Format id
186
     * @return  string              Format code
187
     */
188
    public static function getFormatCode($type)
189
    {
190
        $formatcode = array(
191
            self::$EXPORT_TYPE_CONFIGURABLE => 'csv',
192
            self::$EXPORT_TYPE_CEGID => 'cegid',
193
            self::$EXPORT_TYPE_COALA => 'coala',
194
            self::$EXPORT_TYPE_BOB50 => 'bob50',
195
            self::$EXPORT_TYPE_CIEL => 'ciel',
196
            self::$EXPORT_TYPE_QUADRATUS => 'quadratus',
197
            self::$EXPORT_TYPE_WINFIC => 'winfic',
198
            self::$EXPORT_TYPE_EBP => 'ebp',
199
            self::$EXPORT_TYPE_COGILOG => 'cogilog',
200
            self::$EXPORT_TYPE_AGIRIS => 'agiris',
201
            self::$EXPORT_TYPE_OPENCONCERTO => 'openconcerto',
202
            self::$EXPORT_TYPE_SAGE50_SWISS => 'sage50ch',
203
            self::$EXPORT_TYPE_CHARLEMAGNE => 'charlemagne',
204
            self::$EXPORT_TYPE_LDCOMPTA => 'ldcompta',
205
            self::$EXPORT_TYPE_LDCOMPTA10 => 'ldcompta10',
206
            self::$EXPORT_TYPE_GESTIMUMV3 => 'gestimumv3',
207
            self::$EXPORT_TYPE_GESTIMUMV5 => 'gestimumv5',
208
            self::$EXPORT_TYPE_FEC => 'fec',
209
            self::$EXPORT_TYPE_FEC2 => 'fec2',
210
            self::$EXPORT_TYPE_ISUITEEXPERT => 'isuiteexpert',
211
        );
212
213
        global $hookmanager;
214
        $code = $formatcode[$type];
215
        $parameters = array('type' => $type);
216
        $reshook = $hookmanager->executeHooks('getFormatCode', $parameters, $code);
217
218
        return $code;
219
    }
220
221
    /**
222
     * Array with all export type available (key + label) and parameters for config
223
     *
224
     * @return array of type
225
     */
226
    public function getTypeConfig()
227
    {
228
        global $langs;
229
230
        $exporttypes = array(
231
            'param' => array(
232
                self::$EXPORT_TYPE_CONFIGURABLE => array(
233
                    'label' => $langs->trans('Modelcsv_configurable'),
234
                    'ACCOUNTING_EXPORT_FORMAT' => getDolGlobalString('ACCOUNTING_EXPORT_FORMAT', 'txt'),
235
                    'ACCOUNTING_EXPORT_SEPARATORCSV' => getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV', ','),
236
                    'ACCOUNTING_EXPORT_ENDLINE' => getDolGlobalString('ACCOUNTING_EXPORT_ENDLINE', 1),
237
                    'ACCOUNTING_EXPORT_DATE' => getDolGlobalString('ACCOUNTING_EXPORT_DATE', '%Y-%m-%d'),
238
                ),
239
                self::$EXPORT_TYPE_CEGID => array(
240
                    'label' => $langs->trans('Modelcsv_CEGID'),
241
                ),
242
                self::$EXPORT_TYPE_COALA => array(
243
                    'label' => $langs->trans('Modelcsv_COALA'),
244
                ),
245
                self::$EXPORT_TYPE_BOB50 => array(
246
                    'label' => $langs->trans('Modelcsv_bob50'),
247
                ),
248
                self::$EXPORT_TYPE_CIEL => array(
249
                    'label' => $langs->trans('Modelcsv_ciel'),
250
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
251
                ),
252
                self::$EXPORT_TYPE_QUADRATUS => array(
253
                    'label' => $langs->trans('Modelcsv_quadratus'),
254
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
255
                ),
256
                self::$EXPORT_TYPE_WINFIC => array(
257
                    'label' => $langs->trans('Modelcsv_winfic'),
258
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
259
                ),
260
                self::$EXPORT_TYPE_EBP => array(
261
                    'label' => $langs->trans('Modelcsv_ebp'),
262
                ),
263
                self::$EXPORT_TYPE_COGILOG => array(
264
                    'label' => $langs->trans('Modelcsv_cogilog'),
265
                ),
266
                self::$EXPORT_TYPE_AGIRIS => array(
267
                    'label' => $langs->trans('Modelcsv_agiris'),
268
                ),
269
                self::$EXPORT_TYPE_OPENCONCERTO => array(
270
                    'label' => $langs->trans('Modelcsv_openconcerto'),
271
                ),
272
                self::$EXPORT_TYPE_SAGE50_SWISS => array(
273
                    'label' => $langs->trans('Modelcsv_Sage50_Swiss'),
274
                ),
275
                self::$EXPORT_TYPE_CHARLEMAGNE => array(
276
                    'label' => $langs->trans('Modelcsv_charlemagne'),
277
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
278
                ),
279
                self::$EXPORT_TYPE_LDCOMPTA => array(
280
                    'label' => $langs->trans('Modelcsv_LDCompta'),
281
                ),
282
                self::$EXPORT_TYPE_LDCOMPTA10 => array(
283
                    'label' => $langs->trans('Modelcsv_LDCompta10'),
284
                ),
285
                self::$EXPORT_TYPE_GESTIMUMV3 => array(
286
                    'label' => $langs->trans('Modelcsv_Gestinumv3'),
287
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
288
                ),
289
                self::$EXPORT_TYPE_GESTIMUMV5 => array(
290
                    'label' => $langs->trans('Modelcsv_Gestinumv5'),
291
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
292
                ),
293
                self::$EXPORT_TYPE_FEC => array(
294
                    'label' => $langs->trans('Modelcsv_FEC'),
295
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
296
                ),
297
                self::$EXPORT_TYPE_FEC2 => array(
298
                    'label' => $langs->trans('Modelcsv_FEC2'),
299
                    'ACCOUNTING_EXPORT_FORMAT' => 'txt',
300
                ),
301
                self::$EXPORT_TYPE_ISUITEEXPERT => array(
302
                    'label' => 'iSuite Expert',
303
                    'ACCOUNTING_EXPORT_FORMAT' => 'csv',
304
                ),
305
            ),
306
            'cr' => array(
307
                '1' => $langs->trans("Unix"),
308
                '2' => $langs->trans("Windows")
309
            ),
310
            'format' => array(
311
                'csv' => $langs->trans("csv"),
312
                'txt' => $langs->trans("txt")
313
            ),
314
        );
315
316
        global $hookmanager;
317
        $parameters = array();
318
        $reshook = $hookmanager->executeHooks('getTypeConfig', $parameters, $exporttypes);
319
        return $exporttypes;
320
    }
321
322
323
    /**
324
     * Return the MIME type of a file
325
     *
326
     * @param   int     $formatexportset    Id of export format
327
     * @return  string                      MIME type.
328
     */
329
    public function getMimeType($formatexportset)
330
    {
331
        switch ($formatexportset) {
332
            case self::$EXPORT_TYPE_FEC:
333
                $mime = 'text/tab-separated-values';
334
                break;
335
            default:
336
                $mime = 'text/csv';
337
                break;
338
        }
339
340
        return $mime;
341
    }
342
343
    /**
344
     * Function who chose which export to use with the default config, and make the export into a file
345
     *
346
     * @param   array   $TData                      Array with data
347
     * @param   int     $formatexportset            Id of export format
348
     * @param   int     $withAttachment             [=0] Not add files
349
     *                                              or 1 to have attached in an archive (ex : Quadratus) - Force output mode to write in a file (output mode = 1)
350
     * @param   int     $downloadMode               [=0] Direct download. Deprecated. Always use value 1.
351
     *                                              or 1 to download after writing files - Forced by default when use withAttachment = 1
352
     *                                              or -1 not to download files
353
     * @param   int     $outputMode                 [=0] Print on screen. Deprecated. Always use value 1.
354
     *                                              or 1 to write in file and uses the temp directory - Forced by default when use withAttachment = 1
355
     *                                              or 2 to write in file a default export directory (accounting/export/)
356
     * @param   int     $noouput                    0=old mode. Deprecated. Always use value 1.
357
     *                                              or 1=Do not output the file on stdout with this method. This must always be done by the main page, never by a method.
358
     * @return  int                                 Return integer <0 if KO, >0 OK. The property ->generatedfile is also filled.
359
     */
360
    public function export(&$TData, $formatexportset, $withAttachment = 0, $downloadMode = 0, $outputMode = 0, $noouput = 0)
361
    {
362
        global $db, $conf, $langs;  // The tpl file use $db
363
        global $search_date_end;    // Used into /accountancy/tpl/export_journal.tpl.php
364
365
        // Define name of file to save
366
        $filename = 'general_ledger-' . $this->getFormatCode($formatexportset);
367
        $type_export = 'general_ledger';
368
369
        $completefilename = '';
370
        $exportFile = null;
371
        $exportFileName = '';
372
        $exportFilePath = '';
373
        $exportFileFullName = '';
374
        $downloadFileMimeType = '';
375
        $downloadFileFullName = '';
376
        $downloadFilePath = '';
377
        $archiveFullName = '';
378
        $archivePath = '';
379
        $archiveFileList = array();
380
        if ($withAttachment == 1) {
381
            if ($downloadMode == 0) {
382
                $downloadMode = 1; // force to download after writing all files (can't use direct download)
383
            }
384
            if ($outputMode == 0) {
385
                $outputMode = 1; // force to put files in a temp directory (can't use print on screen)
386
            }
387
388
            // PHP ZIP extension must be enabled
389
            if (!extension_loaded('zip')) {
390
                $langs->load('install');
391
                $this->errors[] = $langs->trans('ErrorPHPDoesNotSupport', 'ZIP');
392
                return -1;
393
            }
394
        }
395
396
        $mimetype = $this->getMimeType($formatexportset);
397
        if ($downloadMode == 0) {
398
            // begin to print header for direct download
399
            ViewMain::topHttpHead($mimetype, 1);
400
        }
401
402
        include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
403
404
        if ($outputMode == 1 || $outputMode == 2) {
405
            if ($outputMode == 1) {
406
                // uses the temp directory by default to write files
407
                if (!empty($conf->accounting->multidir_temp[$conf->entity])) {
408
                    $outputDir = $conf->accounting->multidir_temp[$conf->entity];
409
                } else {
410
                    $outputDir = $conf->accounting->dir_temp;
411
                }
412
            } else {
413
                // uses the default export directory "accounting/export"
414
                if (!empty($conf->accounting->multidir_output[$conf->entity])) {
415
                    $outputDir = $conf->accounting->multidir_output[$conf->entity];
416
                } else {
417
                    $outputDir = $conf->accounting->dir_output;
418
                }
419
420
                // directory already created when module is enabled
421
                $outputDir .= '/export';
422
                $outputDir .= '/' . dol_sanitizePathName($formatexportset);
423
            }
424
425
            if (!dol_is_dir($outputDir)) {
426
                if (dol_mkdir($outputDir) < 0) {
427
                    $this->errors[] = $langs->trans('ErrorCanNotCreateDir', $outputDir);
428
                    return -1;
429
                }
430
            }
431
432
            if ($outputDir != '') {
433
                if (!dol_is_dir($outputDir)) {
434
                    $langs->load('errors');
435
                    $this->errors[] = $langs->trans('ErrorDirNotFound', $outputDir);
436
                    return -1;
437
                }
438
439
                if (!empty($completefilename)) {
440
                    // create export file
441
                    $exportFileFullName = $completefilename;
442
                    $exportFileBaseName = basename($exportFileFullName);
443
                    $exportFileName = pathinfo($exportFileBaseName, PATHINFO_FILENAME);
444
                    $exportFilePath = $outputDir . '/' . $exportFileFullName;
445
                    $exportFile = fopen($exportFilePath, 'w');
446
                    if (!$exportFile) {
447
                        $this->errors[] = $langs->trans('ErrorFileNotFound', $exportFilePath);
448
                        return -1;
449
                    }
450
451
                    if ($withAttachment == 1) {
452
                        $archiveFileList[0] = array(
453
                            'path' => $exportFilePath,
454
                            'name' => $exportFileFullName,
455
                        );
456
457
                        // archive name and path
458
                        $archiveFullName = $exportFileName . '.zip';
459
                        $archivePath = $outputDir . '/' . $archiveFullName;
460
                    }
461
                }
462
            }
463
        }
464
465
        // export file (print on screen or write in a file) and prepare archive list if with attachment is set to 1
466
        switch ($formatexportset) {
467
            case self::$EXPORT_TYPE_CONFIGURABLE:
468
                $this->exportConfigurable($TData, $exportFile);
469
                break;
470
            case self::$EXPORT_TYPE_CEGID:
471
                $this->exportCegid($TData, $exportFile);
472
                break;
473
            case self::$EXPORT_TYPE_COALA:
474
                $this->exportCoala($TData, $exportFile);
475
                break;
476
            case self::$EXPORT_TYPE_BOB50:
477
                $this->exportBob50($TData, $exportFile);
478
                break;
479
            case self::$EXPORT_TYPE_CIEL:
480
                $this->exportCiel($TData, $exportFile);
481
                break;
482
            case self::$EXPORT_TYPE_QUADRATUS:
483
                $archiveFileList = $this->exportQuadratus($TData, $exportFile, $archiveFileList, $withAttachment);
484
                break;
485
            case self::$EXPORT_TYPE_WINFIC:
486
                $this->exportWinfic($TData, $exportFile);
487
                break;
488
            case self::$EXPORT_TYPE_EBP:
489
                $this->exportEbp($TData, $exportFile);
490
                break;
491
            case self::$EXPORT_TYPE_COGILOG:
492
                $this->exportCogilog($TData, $exportFile);
493
                break;
494
            case self::$EXPORT_TYPE_AGIRIS:
495
                $this->exportAgiris($TData, $exportFile);
496
                break;
497
            case self::$EXPORT_TYPE_OPENCONCERTO:
498
                $this->exportOpenConcerto($TData, $exportFile);
499
                break;
500
            case self::$EXPORT_TYPE_SAGE50_SWISS:
501
                $this->exportSAGE50SWISS($TData, $exportFile);
502
                break;
503
            case self::$EXPORT_TYPE_CHARLEMAGNE:
504
                $this->exportCharlemagne($TData, $exportFile);
505
                break;
506
            case self::$EXPORT_TYPE_LDCOMPTA:
507
                $this->exportLDCompta($TData, $exportFile);
508
                break;
509
            case self::$EXPORT_TYPE_LDCOMPTA10:
510
                $this->exportLDCompta10($TData, $exportFile);
511
                break;
512
            case self::$EXPORT_TYPE_GESTIMUMV3:
513
                $this->exportGestimumV3($TData, $exportFile);
514
                break;
515
            case self::$EXPORT_TYPE_GESTIMUMV5:
516
                $this->exportGestimumV5($TData, $exportFile);
517
                break;
518
            case self::$EXPORT_TYPE_FEC:
519
                $archiveFileList = $this->exportFEC($TData, $exportFile, $archiveFileList, $withAttachment);
520
                break;
521
            case self::$EXPORT_TYPE_FEC2:
522
                $archiveFileList = $this->exportFEC2($TData, $exportFile, $archiveFileList, $withAttachment);
523
                break;
524
            case self::$EXPORT_TYPE_ISUITEEXPERT:
525
                $this->exportiSuiteExpert($TData, $exportFile);
526
                break;
527
            default:
528
                global $hookmanager;
529
                $parameters = array('format' => $formatexportset);
530
                // file contents will be created in the hooked function via print
531
                $reshook = $hookmanager->executeHooks('export', $parameters, $TData);
532
                if ($reshook != 1) {
533
                    $this->errors[] = $langs->trans('accountancy_error_modelnotfound');
534
                }
535
                break;
536
        }
537
538
539
        // Create and download export file or archive
540
        if ($outputMode == 1 || $outputMode == 2) {
541
            $error = 0;
542
543
            // close export file
544
            if ($exportFile) {
545
                fclose($exportFile);
546
            }
547
548
            if ($withAttachment == 1) {
549
                // create archive file
550
                if (!empty($archiveFullName) && !empty($archivePath) && !empty($archiveFileList)) {
551
                    // archive files
552
                    $downloadFileMimeType = 'application/zip';
553
                    $downloadFileFullName = $archiveFullName;
554
                    $downloadFilePath = $archivePath;
555
556
                    // create archive
557
                    $archive = new ZipArchive();
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Accountancy\Classes\ZipArchive was not found. Did you mean ZipArchive? If so, make sure to prefix the type with \.
Loading history...
558
                    $res = $archive->open($archivePath, ZipArchive::OVERWRITE | ZipArchive::CREATE);
559
                    if ($res !== true) {
560
                        $error++;
561
                        $this->errors[] = $langs->trans('ErrorFileNotFound', $archivePath);
562
                    }
563
                    if (!$error) {
564
                        // add files
565
                        foreach ($archiveFileList as $archiveFileArr) {
566
                            $res = $archive->addFile($archiveFileArr['path'], $archiveFileArr['name']);
567
                            if (!$res) {
568
                                $error++;
569
                                $this->errors[] = $langs->trans('ErrorArchiveAddFile', $archiveFileArr['name']);
570
                                break;
571
                            }
572
                        }
573
                    }
574
                    if (!$error) {
575
                        // close archive
576
                        $archive->close();
577
                    }
578
                }
579
            }
580
581
            if (!$error) {
582
                // download after writing files
583
                if ($downloadMode == 1) {
584
                    if ($withAttachment == 0) {
585
                        // only download exported file
586
                        if (!empty($exportFileFullName) && !empty($exportFilePath)) {
587
                            $downloadFileMimeType = $mimetype;
588
                            $downloadFileFullName = $exportFileFullName;
589
                            $downloadFilePath = $exportFilePath;
590
                        }
591
                    }
592
593
                    // download export file or archive
594
                    if (!empty($downloadFileMimeType) && !empty($downloadFileFullName) && !empty($downloadFilePath) && empty($noouput)) {
595
                        // deprecated. We must not use this anymore, but have $noouput = 1 because HTTP header must be sent
596
                        // into main page not into a method.
597
                        header('Content-Type: ' . $downloadFileMimeType);
598
                        header('Content-Disposition: attachment; filename=' . $downloadFileFullName);
599
                        header('Cache-Control: Public, must-revalidate');
600
                        header('Pragma: public');
601
                        header('Content-Length: ' . dol_filesize($downloadFilePath));
602
603
                        readfileLowMemory($downloadFilePath);
604
                    }
605
606
                    $this->generatedfiledata = array('downloadFilePath' => $downloadFilePath, 'downloadFileMimeType' => $downloadFileMimeType, 'downloadFileFullName' => $downloadFileFullName);
607
                }
608
            }
609
610
            if ($error) {
611
                return -1;
612
            }
613
        }
614
615
        return 1;
616
    }
617
618
619
    /**
620
     * Export format : CEGID
621
     *
622
     * @param   array       $objectLines            data
623
     * @param   resource    $exportFile             [=null] File resource to export or print if null
624
     * @return  void
625
     */
626
    public function exportCegid($objectLines, $exportFile = null)
627
    {
628
        $separator = ";";
629
        $end_line = "\n";
630
631
        foreach ($objectLines as $line) {
632
            $date_document = dol_print_date($line->doc_date, '%d%m%Y');
633
634
            $tab = array();
635
636
            $tab[] = $date_document;
637
            $tab[] = $line->code_journal;
638
            $tab[] = length_accountg($line->numero_compte);
639
            $tab[] = length_accounta($line->subledger_account);
640
            $tab[] = $line->sens;
641
            $tab[] = price2fec(abs($line->debit - $line->credit));
642
            $tab[] = dol_string_unaccent($line->label_operation);
643
            $tab[] = dol_string_unaccent($line->doc_ref);
644
645
            $output = implode($separator, $tab) . $end_line;
646
            if ($exportFile) {
647
                fwrite($exportFile, $output);
648
            } else {
649
                print $output;
650
            }
651
        }
652
    }
653
654
    /**
655
     * Export format : COGILOG
656
     * Last review for this format : 2022-07-12 Alexandre Spangaro ([email protected])
657
     *
658
     * @param   array       $objectLines            data
659
     * @param   resource    $exportFile             [=null] File resource to export or print if null
660
     * @return  void
661
     */
662
    public function exportCogilog($objectLines, $exportFile = null)
663
    {
664
        $separator = "\t";
665
        $end_line = "\n";
666
667
        foreach ($objectLines as $line) {
668
            $date_document = dol_print_date($line->doc_date, '%d%m%Y');
669
670
            $refInvoice = '';
671
            if ($line->doc_type == 'customer_invoice') {
672
                // Customer invoice
673
                $invoice = new Facture($this->db);
674
                $invoice->fetch($line->fk_doc);
675
676
                $refInvoice = $invoice->ref;
677
            } elseif ($line->doc_type == 'supplier_invoice') {
678
                // Supplier invoice
679
                $invoice = new FactureFournisseur($this->db);
680
                $invoice->fetch($line->fk_doc);
681
682
                $refInvoice = $invoice->ref_supplier;
683
            }
684
685
            $tab = array();
686
687
            $tab[] = $line->code_journal;
688
            $tab[] = $date_document;
689
            $tab[] = $refInvoice;
690
            if (empty($line->subledger_account)) {
691
                $tab[] = length_accountg($line->numero_compte);
692
            } else {
693
                $tab[] = length_accounta($line->subledger_account);
694
            }
695
            $tab[] = "";
696
            $tab[] = $line->label_operation;
697
            $tab[] = $date_document;
698
            if ($line->sens == 'D') {
699
                $tab[] = price($line->debit);
700
                $tab[] = "";
701
            } elseif ($line->sens == 'C') {
702
                $tab[] = "";
703
                $tab[] = price($line->credit);
704
            }
705
            $tab[] = $line->doc_ref;
706
            $tab[] = $line->label_operation;
707
708
            $output = implode($separator, $tab) . $end_line;
709
            if ($exportFile) {
710
                fwrite($exportFile, $output);
711
            } else {
712
                print $output;
713
            }
714
        }
715
    }
716
717
    /**
718
     * Export format : COALA
719
     *
720
     * @param   array       $objectLines            data
721
     * @param   resource    $exportFile             [=null] File resource to export or print if null
722
     * @return  void
723
     */
724
    public function exportCoala($objectLines, $exportFile = null)
725
    {
726
        // Coala export
727
        $separator = ";";
728
        $end_line = "\n";
729
730
        foreach ($objectLines as $line) {
731
            $date_document = dol_print_date($line->doc_date, '%d/%m/%Y');
732
733
            $tab = array();
734
735
            $tab[] = $date_document;
736
            $tab[] = $line->code_journal;
737
            $tab[] = length_accountg($line->numero_compte);
738
            $tab[] = $line->piece_num;
739
            $tab[] = $line->doc_ref;
740
            $tab[] = price($line->debit);
741
            $tab[] = price($line->credit);
742
            $tab[] = 'E';
743
            $tab[] = length_accounta($line->subledger_account);
744
745
            $output = implode($separator, $tab) . $end_line;
746
            if ($exportFile) {
747
                fwrite($exportFile, $output);
748
            } else {
749
                print $output;
750
            }
751
        }
752
    }
753
754
    /**
755
     * Export format : BOB50
756
     *
757
     * @param   array       $objectLines            data
758
     * @param   resource    $exportFile             [=null] File resource to export or print if null
759
     * @return  void
760
     */
761
    public function exportBob50($objectLines, $exportFile = null)
762
    {
763
        // Bob50
764
        $separator = ";";
765
        $end_line = "\n";
766
767
        foreach ($objectLines as $line) {
768
            $date_document = dol_print_date($line->doc_date, '%d/%m/%Y');
769
770
            $tab = array();
771
772
            $tab[] = $line->piece_num;
773
            $tab[] = $date_document;
774
775
            if (empty($line->subledger_account)) {
776
                $tab[] = 'G';
777
                $tab[] = length_accountg($line->numero_compte);
778
            } else {
779
                if (substr($line->numero_compte, 0, 3) == '411') {
780
                    $tab[] = 'C';
781
                }
782
                if (substr($line->numero_compte, 0, 3) == '401') {
783
                    $tab[] = 'F';
784
                }
785
                $tab[] = length_accounta($line->subledger_account);
786
            }
787
788
            $tab[] = price($line->debit);
789
            $tab[] = price($line->credit);
790
            $tab[] = dol_trunc($line->label_operation, 32);
791
792
            $output = implode($separator, $tab) . $end_line;
793
            if ($exportFile) {
794
                fwrite($exportFile, $output);
795
            } else {
796
                print $output;
797
            }
798
        }
799
    }
800
801
    /**
802
     * Export format : CIEL (Format XIMPORT)
803
     * Format since 2003 compatible CIEL version > 2002 / Sage50
804
     * Last review for this format : 2021-09-13 Alexandre Spangaro ([email protected])
805
     *
806
     * Help : https://sage50c.online-help.sage.fr/aide-technique/
807
     * In sage software | Use menu : "Exchange" > "Importing entries..."
808
     *
809
     * If you want to force filename to "XIMPORT.TXT" for automatically import file present in a directory :
810
     * use constant ACCOUNTING_EXPORT_XIMPORT_FORCE_FILENAME
811
     *
812
     * @param   array       $objectLines            data
813
     * @param   resource    $exportFile             [=null] File resource to export or print if null
814
     * @return  void
815
     */
816
    public function exportCiel($objectLines, $exportFile = null)
817
    {
818
        $end_line = "\r\n";
819
820
        $i = 1;
821
822
        foreach ($objectLines as $line) {
823
            $code_compta = length_accountg($line->numero_compte);
824
            if (!empty($line->subledger_account)) {
825
                $code_compta = length_accounta($line->subledger_account);
826
            }
827
828
            $date_document = dol_print_date($line->doc_date, '%Y%m%d');
829
            $date_echeance = dol_print_date($line->date_lim_reglement, '%Y%m%d');
830
831
            $tab = array();
832
833
            $tab[] = str_pad($line->piece_num, 5);
834
            $tab[] = str_pad(self::trunc($line->code_journal, 2), 2);
835
            $tab[] = str_pad($date_document, 8, ' ', STR_PAD_LEFT);
836
            $tab[] = str_pad($date_echeance, 8, ' ', STR_PAD_LEFT);
837
            $tab[] = str_pad(self::trunc($line->doc_ref, 12), 12);
838
            $tab[] = str_pad(self::trunc($code_compta, 11), 11);
839
            $tab[] = str_pad(self::trunc(dol_string_unaccent($line->doc_ref) . dol_string_unaccent($line->label_operation), 25), 25);
840
            $tab[] = str_pad(price2fec(abs($line->debit - $line->credit)), 13, ' ', STR_PAD_LEFT);
841
            $tab[] = str_pad($line->sens, 1);
842
            $tab[] = str_repeat(' ', 18); // Analytical accounting - Not managed in Dolibarr
843
            $tab[] = str_pad(self::trunc(dol_string_unaccent($line->label_operation), 34), 34);
844
            $tab[] = 'O2003'; // 0 = EUR | 2003 = Format Ciel
845
846
            $output = implode($tab) . $end_line;
847
            if ($exportFile) {
848
                fwrite($exportFile, $output);
849
            } else {
850
                print $output;
851
            }
852
            $i++;
853
        }
854
    }
855
856
    /**
857
     * Export format : Quadratus (Format ASCII)
858
     * Format since 2015 compatible QuadraCOMPTA
859
     * Last review for this format : 2023/10/12 Alexandre Spangaro ([email protected])
860
     *
861
     * Information on format: https://docplayer.fr/20769649-Fichier-d-entree-ascii-dans-quadracompta.html
862
     * Help to import in Quadra: https://wiki.dolibarr.org/index.php?title=Module_Comptabilit%C3%A9_en_Partie_Double#Import_vers_CEGID_Quadra
863
     * In QuadraCompta | Use menu : "Outils" > "Suivi des dossiers" > "Import ASCII(Compta)"
864
     *
865
     * @param   array       $objectLines            data
866
     * @param   resource    $exportFile             [=null] File resource to export or print if null
867
     * @param   array       $archiveFileList        [=array()] Archive file list : array of ['path', 'name']
868
     * @param   int         $withAttachment         [=0] Not add files or 1 to have attached in an archive
869
     * @return  array       Archive file list : array of ['path', 'name']
870
     */
871
    public function exportQuadratus($objectLines, $exportFile = null, $archiveFileList = array(), $withAttachment = 0)
872
    {
873
        global $conf, $db;
874
875
        $end_line = "\r\n";
876
877
        // We should use dol_now function not time however this is wrong date to transfer in accounting
878
        foreach ($objectLines as $line) {
879
            // Clean some data
880
            $line->doc_ref = dol_string_unaccent($line->doc_ref);
881
882
            $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
883
            $line->label_operation = str_replace(array("- ", "…", "..."), "", $line->label_operation);
884
            $line->label_operation = dol_string_unaccent($line->label_operation);
885
886
            $line->numero_compte = dol_string_unaccent($line->numero_compte);
887
            $line->label_compte = dol_string_unaccent($line->label_compte);
888
            $line->subledger_account = dol_string_unaccent($line->subledger_account);
889
890
            $line->subledger_label = str_replace(array("- ", "…", "..."), "", $line->subledger_label);
891
            $line->subledger_label = dol_string_unaccent($line->subledger_label);
892
893
            $code_compta = $line->numero_compte;
894
            if (!empty($line->subledger_account)) {
895
                $code_compta = $line->subledger_account;
896
            }
897
898
            $tab = array();
899
900
            if (!empty($line->subledger_account)) {
901
                $tab['type_ligne'] = 'C';
902
                $tab['num_compte'] = str_pad(self::trunc($line->subledger_account, 8), 8);
903
                $tab['lib_compte'] = str_pad(self::trunc($line->subledger_label, 30), 30);
904
905
                if ($line->doc_type == 'customer_invoice') {
906
                    $tab['lib_alpha'] = strtoupper(str_pad('C' . self::trunc(dol_string_unaccent($line->subledger_label), 6), 7));
907
                    $tab['filler'] = str_repeat(' ', 52);
908
                    $tab['coll_compte'] = str_pad(self::trunc(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), 8), 8);
909
                } elseif ($line->doc_type == 'supplier_invoice') {
910
                    $tab['lib_alpha'] = strtoupper(str_pad('F' . self::trunc(dol_string_unaccent($line->subledger_label), 6), 7));
911
                    $tab['filler'] = str_repeat(' ', 52);
912
                    $tab['coll_compte'] = str_pad(self::trunc(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), 8), 8);
913
                } else {
914
                    $tab['filler'] = str_repeat(' ', 59);
915
                    $tab['coll_compte'] = str_pad(' ', 8);
916
                }
917
918
                $tab['filler2'] = str_repeat(' ', 110);
919
                $tab['Maj'] = 2; // Partial update (alpha key, label, address, collectif, RIB)
920
921
                if ($line->doc_type == 'customer_invoice') {
922
                    $tab['type_compte'] = 'C';
923
                } elseif ($line->doc_type == 'supplier_invoice') {
924
                    $tab['type_compte'] = 'F';
925
                } else {
926
                    $tab['type_compte'] = 'G';
927
                }
928
929
                $tab['filler3'] = str_repeat(' ', 235);
930
931
                $tab['end_line'] = $end_line;
932
933
                if ($exportFile) {
934
                    fwrite($exportFile, implode($tab));
935
                } else {
936
                    print implode($tab);
937
                }
938
            }
939
940
            $tab = array();
941
            $tab['type_ligne'] = 'M';
942
            $tab['num_compte'] = str_pad(self::trunc($code_compta, 8), 8);
943
            $tab['code_journal'] = str_pad(self::trunc($line->code_journal, 2), 2);
944
            $tab['folio'] = '000';
945
946
            // We use invoice date $line->doc_date not $date_ecriture which is the transfer date
947
            // maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ?
948
            //$tab['date_ecriture'] = $date_ecriture;
949
            $tab['date_ecriture'] = dol_print_date($line->doc_date, '%d%m%y');
950
            $tab['filler'] = ' ';
951
            $tab['libelle_ecriture'] = str_pad(self::trunc($line->doc_ref . ' ' . $line->label_operation, 20), 20);
952
953
            // Credit invoice - invert sens
954
            /*
955
            if ($line->montant < 0) {
956
                if ($line->sens == 'C') {
957
                    $tab['sens'] = 'D';
958
                } else {
959
                    $tab['sens'] = 'C';
960
                }
961
                $tab['signe_montant'] = '-';
962
            } else {
963
                $tab['sens'] = $line->sens; // C or D
964
                $tab['signe_montant'] = '+';
965
            }*/
966
            $tab['sens'] = $line->sens; // C or D
967
            $tab['signe_montant'] = '+';
968
969
            // The amount must be in centimes without decimal points.
970
            $tab['montant'] = str_pad((string) abs(($line->debit - $line->credit) * 100), 12, '0', STR_PAD_LEFT);
971
            $tab['contrepartie'] = str_repeat(' ', 8);
972
973
            // Force date format : %d%m%y
974
            if (!empty($line->date_lim_reglement)) {
975
                $tab['date_echeance'] = dol_print_date($line->date_lim_reglement, '%d%m%y'); // Format must be ddmmyy
976
            } else {
977
                $tab['date_echeance'] = '000000';
978
            }
979
980
            // Please keep quadra named field lettrage(2) + codestat(3) instead of fake lettrage(5)
981
            // $tab['lettrage'] = str_repeat(' ', 5);
982
            $tab['lettrage'] = str_repeat(' ', 2);
983
            $tab['codestat'] = str_repeat(' ', 3);
984
            $tab['num_piece'] = str_pad(self::trunc($line->piece_num, 5), 5);
985
986
            // Keep correct quadra named field instead of anon filler
987
            // $tab['filler2'] = str_repeat(' ', 20);
988
            $tab['affaire'] = str_repeat(' ', 10);
989
            $tab['quantity1'] = str_repeat(' ', 10);
990
            $tab['num_piece2'] = str_pad(self::trunc($line->piece_num, 8), 8);
991
            $tab['devis'] = str_pad($conf->currency, 3);
992
            $tab['code_journal2'] = str_pad(self::trunc($line->code_journal, 3), 3);
993
            $tab['filler3'] = str_repeat(' ', 3);
994
995
            // Keep correct quadra named field instead of anon filler libelle_ecriture2 is 30 char not 32 !!!!
996
            // as we use utf8, we must remove accent to have only one ascii char instead of utf8 2 chars for specials that report wrong line size that will exceed import format spec
997
            // TODO: we should filter more than only accent to avoid wrong line size
998
            // TODO: remove invoice number doc_ref in label,
999
            // TODO: we should offer an option for customer to build the label using invoice number / name / date in accounting software
1000
            //$tab['libelle_ecriture2'] = str_pad(self::trunc($line->doc_ref . ' ' . $line->label_operation, 30), 30);
1001
            $tab['libelle_ecriture2'] = str_pad(self::trunc($line->label_operation, 30), 30);
1002
            $tab['codetva'] = str_repeat(' ', 2);
1003
1004
            // We need to keep the 10 latest number of invoices doc_ref not the beginning part that is the useless almost same part
1005
            // $tab['num_piece3'] = str_pad(self::trunc($line->piece_num, 10), 10);
1006
            $tab['num_piece3'] = substr(self::trunc($line->doc_ref, 20), -10);
1007
            $tab['reserved'] = str_repeat(' ', 10); // position 159
1008
            $tab['currency_amount'] = str_repeat(' ', 13); // position 169
1009
            // get document file
1010
            $attachmentFileName = '';
1011
            if ($withAttachment == 1) {
1012
                $attachmentFileKey = trim($line->piece_num);
1013
1014
                if (!isset($archiveFileList[$attachmentFileKey])) {
1015
                    $objectDirPath = '';
1016
                    $objectFileName = dol_sanitizeFileName($line->doc_ref);
1017
                    if ($line->doc_type == 'customer_invoice') {
1018
                        $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output;
1019
                    } elseif ($line->doc_type == 'expense_report') {
1020
                        $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output;
1021
                    } elseif ($line->doc_type == 'supplier_invoice') {
1022
                        $invoice = new FactureFournisseur($this->db);
1023
                        $invoice->fetch($line->fk_doc);
1024
                        $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output;
1025
                        $objectDirPath .= '/' . rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/');
1026
                    }
1027
                    $arrayofinclusion = array();
1028
                    // If it is a supplier invoice, we want to use last uploaded file
1029
                    $arrayofinclusion[] = '^' . preg_quote($objectFileName, '/') . (($line->doc_type == 'supplier_invoice') ? '.+' : '') . '\.pdf$';
1030
                    $fileFoundList = dol_dir_list($objectDirPath . '/' . $objectFileName, 'files', 0, implode('|', $arrayofinclusion), '(\.meta|_preview.*\.png)$', 'date', SORT_DESC, 0, true);
1031
                    if (!empty($fileFoundList)) {
1032
                        $attachmentFileNameTrunc = str_pad(self::trunc($line->piece_num, 8), 8, '0', STR_PAD_LEFT);
1033
                        foreach ($fileFoundList as $fileFound) {
1034
                            if (strstr($fileFound['name'], $objectFileName)) {
1035
                                // skip native invoice pdfs (canelle)
1036
                                // We want to retrieve an attachment representative of the supplier invoice, not a fake document generated by Dolibarr.
1037
                                if ($line->doc_type == 'supplier_invoice') {
1038
                                    if ($fileFound['name'] === $objectFileName . '.pdf') {
1039
                                        continue;
1040
                                    }
1041
                                } elseif ($fileFound['name'] !== $objectFileName . '.pdf') {
1042
                                    continue;
1043
                                }
1044
                                $fileFoundPath = $objectDirPath . '/' . $objectFileName . '/' . $fileFound['name'];
1045
                                if (file_exists($fileFoundPath)) {
1046
                                    $archiveFileList[$attachmentFileKey] = array(
1047
                                        'path' => $fileFoundPath,
1048
                                        'name' => $attachmentFileNameTrunc . '.pdf',
1049
                                    );
1050
                                    break;
1051
                                }
1052
                            }
1053
                        }
1054
                    }
1055
                }
1056
1057
                if (isset($archiveFileList[$attachmentFileKey])) {
1058
                    $attachmentFileName = $archiveFileList[$attachmentFileKey]['name'];
1059
                }
1060
            }
1061
            if (dol_strlen($attachmentFileName) == 12) {
1062
                $tab['attachment'] = $attachmentFileName; // position 182
1063
            } else {
1064
                $tab['attachment'] = str_repeat(' ', 12); // position 182
1065
            }
1066
            $tab['filler4'] = str_repeat(' ', 38);
1067
            $tab['end_line'] = $end_line;
1068
1069
            if ($exportFile) {
1070
                fwrite($exportFile, implode($tab));
1071
            } else {
1072
                print implode($tab);
1073
            }
1074
        }
1075
1076
        return $archiveFileList;
1077
    }
1078
1079
    /**
1080
     * Export format : WinFic - eWinfic - WinSis Compta
1081
     * Last review for this format : 2022-11-01 Alexandre Spangaro ([email protected])
1082
     *
1083
     * Help : https://wiki.gestan.fr/lib/exe/fetch.php?media=wiki:v15:compta:accountancy-format_winfic-ewinfic-winsiscompta.pdf
1084
     *
1085
     * @param   array       $objectLines            data
1086
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1087
     * @return  void
1088
     */
1089
    public function exportWinfic($objectLines, $exportFile = null)
1090
    {
1091
        global $conf;
1092
1093
        $end_line = "\r\n";
1094
        $index = 1;
1095
1096
        // Warning ! When truncation is necessary, no dot because 3 dots = three characters. The columns are shifted
1097
1098
        foreach ($objectLines as $line) {
1099
            $code_compta = $line->numero_compte;
1100
            if (!empty($line->subledger_account)) {
1101
                $code_compta = $line->subledger_account;
1102
            }
1103
1104
            $tab = array();
1105
            //$tab['type_ligne'] = 'M';
1106
            $tab['code_journal'] = str_pad(dol_trunc($line->code_journal, 2, 'right', 'UTF-8', 1), 2);
1107
1108
            //We use invoice date $line->doc_date not $date_ecriture which is the transfer date
1109
            //maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ?
1110
            //$tab['date_ecriture'] = $date_ecriture;
1111
            $tab['date_operation'] = dol_print_date($line->doc_date, '%d%m%Y');
1112
1113
            $tab['folio'] = '     1';
1114
1115
            $tab['num_ecriture'] = str_pad(dol_trunc($index, 6, 'right', 'UTF-8', 1), 6, ' ', STR_PAD_LEFT);
1116
1117
            $tab['jour_ecriture'] = dol_print_date($line->doc_date, '%d%m%y');
1118
1119
            $tab['num_compte'] = str_pad(dol_trunc($code_compta, 6, 'right', 'UTF-8', 1), 6, '0');
1120
1121
            if ($line->sens == 'D') {
1122
                $tab['montant_debit']  = str_pad(number_format($line->debit, 2, ',', ''), 13, ' ', STR_PAD_LEFT);
1123
1124
                $tab['montant_crebit'] = str_pad(number_format(0, 2, ',', ''), 13, ' ', STR_PAD_LEFT);
1125
            } else {
1126
                $tab['montant_debit']  = str_pad(number_format(0, 2, ',', ''), 13, ' ', STR_PAD_LEFT);
1127
1128
                $tab['montant_crebit'] = str_pad(number_format($line->credit, 2, ',', ''), 13, ' ', STR_PAD_LEFT);
1129
            }
1130
1131
            $tab['libelle_ecriture'] = str_pad(dol_trunc(dol_string_unaccent($line->doc_ref) . ' ' . dol_string_unaccent($line->label_operation), 30, 'right', 'UTF-8', 1), 30);
1132
1133
            $tab['lettrage'] = str_repeat(dol_trunc($line->lettering_code, 2, 'left', 'UTF-8', 1), 2);
1134
1135
            $tab['code_piece'] = str_pad(dol_trunc($line->piece_num, 5, 'left', 'UTF-8', 1), 5, ' ', STR_PAD_LEFT);
1136
1137
            $tab['code_stat'] = str_repeat(' ', 4);
1138
1139
            if (!empty($line->date_lim_reglement)) {
1140
                $tab['date_echeance'] = dol_print_date($line->date_lim_reglement, '%d%m%Y');
1141
            } else {
1142
                $tab['date_echeance'] = dol_print_date($line->doc_date, '%d%m%Y');
1143
            }
1144
1145
            $tab['monnaie'] = '1';
1146
1147
            $tab['filler'] = ' ';
1148
1149
            $tab['ind_compteur'] = ' ';
1150
1151
            $tab['quantite'] = '0,000000000';
1152
1153
            $tab['code_pointage'] = str_repeat(' ', 2);
1154
1155
            $tab['end_line'] = $end_line;
1156
1157
            print implode('|', $tab);
1158
1159
            $index++;
1160
        }
1161
    }
1162
1163
1164
    /**
1165
     * Export format : EBP
1166
     *
1167
     * @param   array       $objectLines            data
1168
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1169
     * @return  void
1170
     */
1171
    public function exportEbp($objectLines, $exportFile = null)
1172
    {
1173
        $separator = ',';
1174
        $end_line = "\n";
1175
1176
        foreach ($objectLines as $line) {
1177
            $date_document = dol_print_date($line->doc_date, '%d%m%Y');
1178
1179
            $tab = array();
1180
1181
            $tab[] = $line->id;
1182
            $tab[] = $date_document;
1183
            $tab[] = $line->code_journal;
1184
            if (empty($line->subledger_account)) {
1185
                $tab[] = $line->numero_compte;
1186
            } else {
1187
                $tab[] = $line->subledger_account;
1188
            }
1189
            //$tab[] = substr(length_accountg($line->numero_compte), 0, 2) . $separator;
1190
            $tab[] = '"' . dol_trunc($line->label_operation, 40, 'right', 'UTF-8', 1) . '"';
1191
            $tab[] = '"' . dol_trunc($line->piece_num, 15, 'right', 'UTF-8', 1) . '"';
1192
            $tab[] = price2num(abs($line->debit - $line->credit));
1193
            $tab[] = $line->sens;
1194
            $tab[] = $date_document;
1195
            //print 'EUR';
1196
1197
            $output = implode($separator, $tab) . $end_line;
1198
            if ($exportFile) {
1199
                fwrite($exportFile, $output);
1200
            } else {
1201
                print $output;
1202
            }
1203
        }
1204
    }
1205
1206
1207
    /**
1208
     * Export format : Agiris Isacompta
1209
     *
1210
     * @param   array       $objectLines            data
1211
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1212
     * @return  void
1213
     */
1214
    public function exportAgiris($objectLines, $exportFile = null)
1215
    {
1216
        $separator = ';';
1217
        $end_line = "\n";
1218
1219
        foreach ($objectLines as $line) {
1220
            $date_document = dol_print_date($line->doc_date, '%d%m%Y');
1221
1222
            $tab = array();
1223
1224
            $tab[] = $line->piece_num;
1225
            $tab[] = self::toAnsi($line->label_operation);
1226
            $tab[] = $date_document;
1227
            $tab[] = self::toAnsi($line->label_operation);
1228
1229
            if (empty($line->subledger_account)) {
1230
                $tab[] = length_accountg($line->numero_compte);
1231
                $tab[] = self::toAnsi($line->label_compte);
1232
            } else {
1233
                $tab[] = length_accounta($line->subledger_account);
1234
                $tab[] = self::toAnsi($line->subledger_label);
1235
            }
1236
1237
            $tab[] = self::toAnsi($line->doc_ref);
1238
            $tab[] = price($line->debit);
1239
            $tab[] = price($line->credit);
1240
            $tab[] = price(abs($line->debit - $line->credit));
1241
            $tab[] = $line->sens;
1242
            $tab[] = $line->lettering_code;
1243
            $tab[] = $line->code_journal;
1244
1245
            $output = implode($separator, $tab) . $end_line;
1246
            if ($exportFile) {
1247
                fwrite($exportFile, $output);
1248
            } else {
1249
                print $output;
1250
            }
1251
        }
1252
    }
1253
1254
    /**
1255
     * Export format : OpenConcerto
1256
     *
1257
     * @param   array       $objectLines            data
1258
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1259
     * @return  void
1260
     */
1261
    public function exportOpenConcerto($objectLines, $exportFile = null)
1262
    {
1263
        $separator = ';';
1264
        $end_line = "\n";
1265
1266
        foreach ($objectLines as $line) {
1267
            $date_document = dol_print_date($line->doc_date, '%d/%m/%Y');
1268
1269
            $tab = array();
1270
1271
            $tab[] = $date_document;
1272
            $tab[] = $line->code_journal;
1273
            if (empty($line->subledger_account)) {
1274
                $tab[] = length_accountg($line->numero_compte);
1275
            } else {
1276
                $tab[] = length_accounta($line->subledger_account);
1277
            }
1278
            $tab[] = $line->doc_ref;
1279
            $tab[] = $line->label_operation;
1280
            $tab[] = price($line->debit);
1281
            $tab[] = price($line->credit);
1282
1283
            $output = implode($separator, $tab) . $end_line;
1284
            if ($exportFile) {
1285
                fwrite($exportFile, $output);
1286
            } else {
1287
                print $output;
1288
            }
1289
        }
1290
    }
1291
1292
    /**
1293
     * Export format : Configurable CSV
1294
     *
1295
     * @param   array       $objectLines            data
1296
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1297
     * @return  void
1298
     */
1299
    public function exportConfigurable($objectLines, $exportFile = null)
1300
    {
1301
        global $conf;
1302
1303
        $separator = $this->separator;
1304
1305
        foreach ($objectLines as $line) {
1306
            $date_document = dol_print_date($line->doc_date, getDolGlobalString('ACCOUNTING_EXPORT_DATE'));
1307
1308
            $tab = array();
1309
            // export configurable
1310
            $tab[] = $line->piece_num;
1311
            $tab[] = $date_document;
1312
            $tab[] = $line->doc_ref;
1313
            $tab[] = preg_match('/' . $separator . '/', $line->label_operation) ? "'" . $line->label_operation . "'" : $line->label_operation;
1314
            $tab[] = length_accountg($line->numero_compte);
1315
            $tab[] = length_accounta($line->subledger_account);
1316
            $tab[] = price2num($line->debit);
1317
            $tab[] = price2num($line->credit);
1318
            $tab[] = price2num($line->debit - $line->credit);
1319
            $tab[] = $line->code_journal;
1320
1321
            $output = implode($separator, $tab) . $this->end_line;
1322
            if ($exportFile) {
1323
                fwrite($exportFile, $output);
1324
            } else {
1325
                print $output;
1326
            }
1327
        }
1328
    }
1329
1330
    /**
1331
     * Export format : FEC
1332
     * Last review for this format : 2023/10/12 Alexandre Spangaro ([email protected])
1333
     *
1334
     * Help to import in your software: https://wiki.dolibarr.org/index.php?title=Module_Comptabilit%C3%A9_en_Partie_Double#Exports_avec_fichiers_sources
1335
     *
1336
     * @param   array       $objectLines            data
1337
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1338
     * @param   array       $archiveFileList        [=array()] Archive file list : array of ['path', 'name']
1339
     * @param   int         $withAttachment         [=0] Not add files or 1 to have attached in an archive
1340
     * @return  array       Archive file list : array of ['path', 'name']
1341
     */
1342
    public function exportFEC($objectLines, $exportFile = null, $archiveFileList = array(), $withAttachment = 0)
1343
    {
1344
        global $conf, $langs;
1345
1346
        $separator = "\t";
1347
        $end_line = "\r\n";
1348
1349
        $tab = array();
1350
        $tab[] = "JournalCode";
1351
        $tab[] = "JournalLib";
1352
        $tab[] = "EcritureNum";
1353
        $tab[] = "EcritureDate";
1354
        $tab[] = "CompteNum";
1355
        $tab[] = "CompteLib";
1356
        $tab[] = "CompAuxNum";
1357
        $tab[] = "CompAuxLib";
1358
        $tab[] = "PieceRef";
1359
        $tab[] = "PieceDate";
1360
        $tab[] = "EcritureLib";
1361
        $tab[] = "Debit";
1362
        $tab[] = "Credit";
1363
        $tab[] = "EcritureLet";
1364
        $tab[] = "DateLet";
1365
        $tab[] = "ValidDate";
1366
        $tab[] = "Montantdevise";
1367
        $tab[] = "Idevise";
1368
        $tab[] = "DateLimitReglmt";
1369
        $tab[] = "NumFacture";
1370
        $tab[] = "FichierFacture";
1371
1372
        $output = implode($separator, $tab) . $end_line;
1373
        if ($exportFile) {
1374
            fwrite($exportFile, $output);
1375
        } else {
1376
            print $output;
1377
        }
1378
1379
        foreach ($objectLines as $line) {
1380
            if ($line->debit == 0 && $line->credit == 0) {
1381
                //var_dump($line->id);
1382
                //unset($array[$line]);
1383
            } else {
1384
                $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
1385
                $date_document = dol_print_date($line->doc_date, '%Y%m%d');
1386
                $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d');
1387
                $date_validation = dol_print_date($line->date_validation, '%Y%m%d');
1388
                $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d');
1389
1390
                $refInvoice = '';
1391
                if ($line->doc_type == 'customer_invoice') {
1392
                    // Customer invoice
1393
                    $invoice = new Facture($this->db);
1394
                    $invoice->fetch($line->fk_doc);
1395
1396
                    $refInvoice = $invoice->ref;
1397
                } elseif ($line->doc_type == 'supplier_invoice') {
1398
                    // Supplier invoice
1399
                    $invoice = new FactureFournisseur($this->db);
1400
                    $invoice->fetch($line->fk_doc);
1401
1402
                    $refInvoice = $invoice->ref_supplier;
1403
                }
1404
1405
                $tab = array();
1406
1407
                // FEC:JournalCode
1408
                $tab[] = $line->code_journal;
1409
1410
                // FEC:JournalLib
1411
                $labeljournal = dol_string_unaccent($langs->transnoentities($line->journal_label));
1412
                $labeljournal = dol_string_nospecial($labeljournal, ' ');
1413
                $tab[] = $labeljournal;
1414
1415
                // FEC:EcritureNum
1416
                $tab[] = $line->piece_num;
1417
1418
                // FEC:EcritureDate
1419
                $tab[] = $date_document;
1420
1421
                // FEC:CompteNum
1422
                $tab[] = length_accountg($line->numero_compte);
1423
1424
                // FEC:CompteLib
1425
                $tab[] = dol_string_unaccent($line->label_compte);
1426
1427
                // FEC:CompAuxNum
1428
                $tab[] = length_accounta($line->subledger_account);
1429
1430
                // FEC:CompAuxLib
1431
                $tab[] = dol_string_unaccent($line->subledger_label);
1432
1433
                // FEC:PieceRef
1434
                $tab[] = $line->doc_ref;
1435
1436
                // FEC:PieceDate
1437
                $tab[] = dol_string_unaccent($date_creation);
1438
1439
                // FEC:EcritureLib
1440
                // Clean label operation to prevent problem on export with tab separator & other character
1441
                $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
1442
                $line->label_operation = str_replace(array("..."), "", $line->label_operation);
1443
                $tab[] = dol_string_unaccent($line->label_operation);
1444
1445
                // FEC:Debit
1446
                $tab[] = price2fec($line->debit);
1447
1448
                // FEC:Credit
1449
                $tab[] = price2fec($line->credit);
1450
1451
                // FEC:EcritureLet
1452
                $tab[] = $line->lettering_code;
1453
1454
                // FEC:DateLet
1455
                $tab[] = $date_lettering;
1456
1457
                // FEC:ValidDate
1458
                $tab[] = $date_validation;
1459
1460
                // FEC:Montantdevise
1461
                $tab[] = $line->multicurrency_amount;
1462
1463
                // FEC:Idevise
1464
                $tab[] = $line->multicurrency_code;
1465
1466
                // FEC_suppl:DateLimitReglmt
1467
                $tab[] = $date_limit_payment;
1468
1469
                // FEC_suppl:NumFacture
1470
                // Clean ref invoice to prevent problem on export with tab separator & other character
1471
                $refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice);
1472
                $tab[] = dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
1473
1474
                // FEC_suppl:FichierFacture
1475
                // get document file
1476
                $attachmentFileName = '';
1477
                if ($withAttachment == 1) {
1478
                    $attachmentFileKey = trim($line->piece_num);
1479
1480
                    if (!isset($archiveFileList[$attachmentFileKey])) {
1481
                        $objectDirPath = '';
1482
                        $objectFileName = dol_sanitizeFileName($line->doc_ref);
1483
                        if ($line->doc_type == 'customer_invoice') {
1484
                            $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output;
1485
                        } elseif ($line->doc_type == 'expense_report') {
1486
                            $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output;
1487
                        } elseif ($line->doc_type == 'supplier_invoice') {
1488
                            $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output;
1489
                            $objectDirPath .= '/' . rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/');
1490
                        }
1491
                        $arrayofinclusion = array();
1492
                        // If it is a supplier invoice, we want to use last uploaded file
1493
                        $arrayofinclusion[] = '^' . preg_quote($objectFileName, '/') . (($line->doc_type == 'supplier_invoice') ? '.+' : '') . '\.pdf$';
1494
                        $fileFoundList = dol_dir_list($objectDirPath . '/' . $objectFileName, 'files', 0, implode('|', $arrayofinclusion), '(\.meta|_preview.*\.png)$', 'date', SORT_DESC, 0, true);
1495
                        if (!empty($fileFoundList)) {
1496
                            $attachmentFileNameTrunc = $line->doc_ref;
1497
                            foreach ($fileFoundList as $fileFound) {
1498
                                if (strstr($fileFound['name'], $objectFileName)) {
1499
                                    // skip native invoice pdfs (canelle)
1500
                                    // We want to retrieve an attachment representative of the supplier invoice, not a fake document generated by Dolibarr.
1501
                                    if ($line->doc_type == 'supplier_invoice') {
1502
                                        if ($fileFound['name'] === $objectFileName . '.pdf') {
1503
                                            continue;
1504
                                        }
1505
                                    } elseif ($fileFound['name'] !== $objectFileName . '.pdf') {
1506
                                        continue;
1507
                                    }
1508
                                    $fileFoundPath = $objectDirPath . '/' . $objectFileName . '/' . $fileFound['name'];
1509
                                    if (file_exists($fileFoundPath)) {
1510
                                        $archiveFileList[$attachmentFileKey] = array(
1511
                                            'path' => $fileFoundPath,
1512
                                            'name' => $attachmentFileNameTrunc . '.pdf',
1513
                                        );
1514
                                        break;
1515
                                    }
1516
                                }
1517
                            }
1518
                        }
1519
                    }
1520
1521
                    if (isset($archiveFileList[$attachmentFileKey])) {
1522
                        $attachmentFileName = $archiveFileList[$attachmentFileKey]['name'];
1523
                    }
1524
                }
1525
1526
                $tab[] = $attachmentFileName;
1527
1528
                $output = implode($separator, $tab) . $end_line;
1529
1530
                if ($exportFile) {
1531
                    fwrite($exportFile, $output);
1532
                } else {
1533
                    print $output;
1534
                }
1535
            }
1536
        }
1537
1538
        return $archiveFileList;
1539
    }
1540
1541
    /**
1542
     * Export format : FEC2
1543
     * Last review for this format : 2023/10/12 Alexandre Spangaro ([email protected])
1544
     *
1545
     * Help to import in your software: https://wiki.dolibarr.org/index.php?title=Module_Comptabilit%C3%A9_en_Partie_Double#Exports_avec_fichiers_sources
1546
     *
1547
     * @param   array       $objectLines            data
1548
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1549
     * @param   array       $archiveFileList        [=array()] Archive file list : array of ['path', 'name']
1550
     * @param   int         $withAttachment         [=0] Not add files or 1 to have attached in an archive
1551
     * @return  array       Archive file list : array of ['path', 'name']
1552
     */
1553
    public function exportFEC2($objectLines, $exportFile = null, $archiveFileList = array(), $withAttachment = 0)
1554
    {
1555
        global $conf, $langs;
1556
1557
        $separator = "\t";
1558
        $end_line = "\r\n";
1559
1560
        $tab = array();
1561
        $tab[] = "JournalCode";
1562
        $tab[] = "JournalLib";
1563
        $tab[] = "EcritureNum";
1564
        $tab[] = "EcritureDate";
1565
        $tab[] = "CompteNum";
1566
        $tab[] = "CompteLib";
1567
        $tab[] = "CompAuxNum";
1568
        $tab[] = "CompAuxLib";
1569
        $tab[] = "PieceRef";
1570
        $tab[] = "PieceDate";
1571
        $tab[] = "EcritureLib";
1572
        $tab[] = "Debit";
1573
        $tab[] = "Credit";
1574
        $tab[] = "EcritureLet";
1575
        $tab[] = "DateLet";
1576
        $tab[] = "ValidDate";
1577
        $tab[] = "Montantdevise";
1578
        $tab[] = "Idevise";
1579
        $tab[] = "DateLimitReglmt";
1580
        $tab[] = "NumFacture";
1581
        $tab[] = "FichierFacture";
1582
1583
        $output = implode($separator, $tab) . $end_line;
1584
        if ($exportFile) {
1585
            fwrite($exportFile, $output);
1586
        } else {
1587
            print $output;
1588
        }
1589
1590
        foreach ($objectLines as $line) {
1591
            if ($line->debit == 0 && $line->credit == 0) {
1592
                //unset($array[$line]);
1593
            } else {
1594
                $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
1595
                $date_document = dol_print_date($line->doc_date, '%Y%m%d');
1596
                $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d');
1597
                $date_validation = dol_print_date($line->date_validation, '%Y%m%d');
1598
                $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d');
1599
1600
                $refInvoice = '';
1601
                if ($line->doc_type == 'customer_invoice') {
1602
                    // Customer invoice
1603
                    $invoice = new Facture($this->db);
1604
                    $invoice->fetch($line->fk_doc);
1605
1606
                    $refInvoice = $invoice->ref;
1607
                } elseif ($line->doc_type == 'supplier_invoice') {
1608
                    // Supplier invoice
1609
                    $invoice = new FactureFournisseur($this->db);
1610
                    $invoice->fetch($line->fk_doc);
1611
1612
                    $refInvoice = $invoice->ref_supplier;
1613
                }
1614
1615
                $tab = array();
1616
1617
                // FEC:JournalCode
1618
                $tab[] = $line->code_journal;
1619
1620
                // FEC:JournalLib
1621
                $labeljournal = dol_string_unaccent($langs->transnoentities($line->journal_label));
1622
                $labeljournal = dol_string_nospecial($labeljournal, ' ');
1623
                $tab[] = $labeljournal;
1624
1625
                // FEC:EcritureNum
1626
                $tab[] = $line->piece_num;
1627
1628
                // FEC:EcritureDate
1629
                $tab[] = $date_creation;
1630
1631
                // FEC:CompteNum
1632
                $tab[] = length_accountg($line->numero_compte);
1633
1634
                // FEC:CompteLib
1635
                $tab[] = dol_string_unaccent($line->label_compte);
1636
1637
                // FEC:CompAuxNum
1638
                $tab[] = length_accounta($line->subledger_account);
1639
1640
                // FEC:CompAuxLib
1641
                $tab[] = dol_string_unaccent($line->subledger_label);
1642
1643
                // FEC:PieceRef
1644
                $tab[] = $line->doc_ref;
1645
1646
                // FEC:PieceDate
1647
                $tab[] = $date_document;
1648
1649
                // FEC:EcritureLib
1650
                // Clean label operation to prevent problem on export with tab separator & other character
1651
                $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
1652
                $line->label_operation = str_replace(array("..."), "", $line->label_operation);
1653
                $tab[] = dol_string_unaccent($line->label_operation);
1654
1655
                // FEC:Debit
1656
                $tab[] = price2fec($line->debit);
1657
1658
                // FEC:Credit
1659
                $tab[] = price2fec($line->credit);
1660
1661
                // FEC:EcritureLet
1662
                $tab[] = $line->lettering_code;
1663
1664
                // FEC:DateLet
1665
                $tab[] = $date_lettering;
1666
1667
                // FEC:ValidDate
1668
                $tab[] = $date_validation;
1669
1670
                // FEC:Montantdevise
1671
                $tab[] = $line->multicurrency_amount;
1672
1673
                // FEC:Idevise
1674
                $tab[] = $line->multicurrency_code;
1675
1676
                // FEC_suppl:DateLimitReglmt
1677
                $tab[] = $date_limit_payment;
1678
1679
                // FEC_suppl:NumFacture
1680
                // Clean ref invoice to prevent problem on export with tab separator & other character
1681
                $refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice);
1682
                $tab[] = dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
1683
1684
                // FEC_suppl:FichierFacture
1685
                // get document file
1686
                $attachmentFileName = '';
1687
                if ($withAttachment == 1) {
1688
                    $attachmentFileKey = trim($line->piece_num);
1689
1690
                    if (!isset($archiveFileList[$attachmentFileKey])) {
1691
                        $objectDirPath = '';
1692
                        $objectFileName = dol_sanitizeFileName($line->doc_ref);
1693
                        if ($line->doc_type == 'customer_invoice') {
1694
                            $objectDirPath = !empty($conf->invoice->multidir_output[$conf->entity]) ? $conf->invoice->multidir_output[$conf->entity] : $conf->invoice->dir_output;
1695
                        } elseif ($line->doc_type == 'expense_report') {
1696
                            $objectDirPath = !empty($conf->expensereport->multidir_output[$conf->entity]) ? $conf->expensereport->multidir_output[$conf->entity] : $conf->expensereport->dir_output;
1697
                        } elseif ($line->doc_type == 'supplier_invoice') {
1698
                            $objectDirPath = !empty($conf->fournisseur->facture->multidir_output[$conf->entity]) ? $conf->fournisseur->facture->multidir_output[$conf->entity] : $conf->fournisseur->facture->dir_output;
1699
                            $objectDirPath .= '/' . rtrim(get_exdir($invoice->id, 2, 0, 0, $invoice, 'invoice_supplier'), '/');
1700
                        }
1701
                        $arrayofinclusion = array();
1702
                        // If it is a supplier invoice, we want to use last uploaded file
1703
                        $arrayofinclusion[] = '^' . preg_quote($objectFileName, '/') . (($line->doc_type == 'supplier_invoice') ? '.+' : '') . '\.pdf$';
1704
                        $fileFoundList = dol_dir_list($objectDirPath . '/' . $objectFileName, 'files', 0, implode('|', $arrayofinclusion), '(\.meta|_preview.*\.png)$', 'date', SORT_DESC, 0, true);
1705
                        if (!empty($fileFoundList)) {
1706
                            $attachmentFileNameTrunc = $line->doc_ref;
1707
                            foreach ($fileFoundList as $fileFound) {
1708
                                if (strstr($fileFound['name'], $objectFileName)) {
1709
                                    // skip native invoice pdfs (canelle)
1710
                                    // We want to retrieve an attachment representative of the supplier invoice, not a fake document generated by Dolibarr.
1711
                                    if ($line->doc_type == 'supplier_invoice') {
1712
                                        if ($fileFound['name'] === $objectFileName . '.pdf') {
1713
                                            continue;
1714
                                        }
1715
                                    } elseif ($fileFound['name'] !== $objectFileName . '.pdf') {
1716
                                        continue;
1717
                                    }
1718
                                    $fileFoundPath = $objectDirPath . '/' . $objectFileName . '/' . $fileFound['name'];
1719
                                    if (file_exists($fileFoundPath)) {
1720
                                        $archiveFileList[$attachmentFileKey] = array(
1721
                                            'path' => $fileFoundPath,
1722
                                            'name' => $attachmentFileNameTrunc . '.pdf',
1723
                                        );
1724
                                        break;
1725
                                    }
1726
                                }
1727
                            }
1728
                        }
1729
                    }
1730
1731
                    if (isset($archiveFileList[$attachmentFileKey])) {
1732
                        $attachmentFileName = $archiveFileList[$attachmentFileKey]['name'];
1733
                    }
1734
                }
1735
1736
                $tab[] = $attachmentFileName;
1737
1738
                $output = implode($separator, $tab) . $end_line;
1739
                if ($exportFile) {
1740
                    fwrite($exportFile, $output);
1741
                } else {
1742
                    print $output;
1743
                }
1744
            }
1745
        }
1746
1747
        return $archiveFileList;
1748
    }
1749
1750
    /**
1751
     * Export format : SAGE50SWISS
1752
     *
1753
     * https://onlinehelp.sageschweiz.ch/default.aspx?tabid=19984
1754
     * http://media.topal.ch/Public/Schnittstellen/TAF/Specification/Sage50-TAF-format.pdf
1755
     *
1756
     * @param   array       $objectLines            data
1757
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1758
     * @return  void
1759
     */
1760
    public function exportSAGE50SWISS($objectLines, $exportFile = null)
1761
    {
1762
        // SAGE50SWISS
1763
        $separator = ',';
1764
        $end_line = "\r\n";
1765
1766
        // Print header line
1767
        $tab = array();
1768
1769
        $tab[] = "Blg";
1770
        $tab[] = "Datum";
1771
        $tab[] = "Kto";
1772
        $tab[] = "S/H";
1773
        $tab[] = "Grp";
1774
        $tab[] = "GKto";
1775
        $tab[] = "SId";
1776
        $tab[] = "SIdx";
1777
        $tab[] = "KIdx";
1778
        $tab[] = "BTyp";
1779
        $tab[] = "MTyp";
1780
        $tab[] = "Code";
1781
        $tab[] = "Netto";
1782
        $tab[] = "Steuer";
1783
        $tab[] = "FW-Betrag";
1784
        $tab[] = "Tx1";
1785
        $tab[] = "Tx2";
1786
        $tab[] = "PkKey";
1787
        $tab[] = "OpId";
1788
        $tab[] = "Flag";
1789
1790
        $output = implode($separator, $tab) . $end_line;
1791
        if ($exportFile) {
1792
            fwrite($exportFile, $output);
1793
        } else {
1794
            print $output;
1795
        }
1796
1797
        $thisPieceNum = "";
1798
        $thisPieceAccountNr = "";
1799
        $aSize = count($objectLines);
1800
        foreach ($objectLines as $aIndex => $line) {
1801
            $sammelBuchung = false;
1802
            if ($aIndex - 2 >= 0 && $objectLines[$aIndex - 2]->piece_num == $line->piece_num) {
1803
                $sammelBuchung = true;
1804
            } elseif ($aIndex + 2 < $aSize && $objectLines[$aIndex + 2]->piece_num == $line->piece_num) {
1805
                $sammelBuchung = true;
1806
            } elseif (
1807
                $aIndex + 1 < $aSize
1808
                    && $objectLines[$aIndex + 1]->piece_num == $line->piece_num
1809
                    && $aIndex - 1 < $aSize
1810
                    && $objectLines[$aIndex - 1]->piece_num == $line->piece_num
1811
            ) {
1812
                $sammelBuchung = true;
1813
            }
1814
1815
            $tab = array();
1816
1817
            //Blg
1818
            $tab[] = $line->piece_num;
1819
1820
            // Datum
1821
            $date_document = dol_print_date($line->doc_date, '%d.%m.%Y');
1822
            $tab[] = $date_document;
1823
1824
            // Kto
1825
            $tab[] = length_accountg($line->numero_compte);
1826
            // S/H
1827
            if ($line->sens == 'D') {
1828
                $tab[] = 'S';
1829
            } else {
1830
                $tab[] = 'H';
1831
            }
1832
            // Grp
1833
            $tab[] = self::trunc($line->code_journal, 1);
1834
            // GKto
1835
            if (empty($line->code_tiers)) {
1836
                if ($line->piece_num == $thisPieceNum) {
1837
                    $tab[] = length_accounta($thisPieceAccountNr);
1838
                } else {
1839
                    $tab[] = "div";
1840
                }
1841
            } else {
1842
                $tab[] = length_accounta($line->code_tiers);
1843
            }
1844
            // SId
1845
            $tab[] = $this->separator;
1846
            // SIdx
1847
            $tab[] = "0";
1848
            // KIdx
1849
            $tab[] = "0";
1850
            // BTyp
1851
            $tab[] = "0";
1852
1853
            // MTyp 1=Fibu Einzelbuchung 2=Sammebuchung
1854
            if ($sammelBuchung) {
1855
                $tab[] = "2";
1856
            } else {
1857
                $tab[] = "1";
1858
            }
1859
            // Code
1860
            $tab[] = '""';
1861
            // Netto
1862
            $tab[] = abs($line->debit - $line->credit);
1863
            // Steuer
1864
            $tab[] = "0.00";
1865
            // FW-Betrag
1866
            $tab[] = "0.00";
1867
            // Tx1
1868
            $line1 = self::toAnsi($line->label_compte, 29);
1869
            if ($line1 == "LIQ" || $line1 == "LIQ Beleg ok" || strlen($line1) <= 3) {
1870
                $line1 = "";
1871
            }
1872
            $line2 = self::toAnsi($line->doc_ref, 29);
1873
            if (strlen($line1) == 0) {
1874
                $line1 = $line2;
1875
                $line2 = "";
1876
            }
1877
            if (strlen($line1) > 0 && strlen($line2) > 0 && (strlen($line1) + strlen($line2)) < 27) {
1878
                $line1 = $line1 . ' / ' . $line2;
1879
                $line2 = "";
1880
            }
1881
1882
            $tab[] = '"' . self::toAnsi($line1) . '"';
1883
            // Tx2
1884
            $tab[] = '"' . self::toAnsi($line2) . '"';
1885
            //PkKey
1886
            $tab[] = "0";
1887
            //OpId
1888
            $tab[] = $this->separator;
1889
1890
            // Flag
1891
            $tab[] = "0";
1892
1893
            $output = implode($separator, $tab) . $end_line;
1894
            if ($exportFile) {
1895
                fwrite($exportFile, $output);
1896
            } else {
1897
                print $output;
1898
            }
1899
1900
            if ($line->piece_num !== $thisPieceNum) {
1901
                $thisPieceNum = $line->piece_num;
1902
                $thisPieceAccountNr = $line->numero_compte;
1903
            }
1904
        }
1905
    }
1906
1907
    /**
1908
     * Export format : LD Compta version 9
1909
     * http://www.ldsysteme.fr/fileadmin/telechargement/np/ldcompta/Documentation/IntCptW9.pdf
1910
     *
1911
     * @param   array       $objectLines            data
1912
     * @param   resource    $exportFile             [=null] File resource to export or print if null
1913
     * @return  void
1914
     */
1915
    public function exportLDCompta($objectLines, $exportFile = null)
1916
    {
1917
        $separator = ';';
1918
        $end_line = "\r\n";
1919
1920
        foreach ($objectLines as $line) {
1921
            $date_document = dol_print_date($line->doc_date, '%Y%m%d');
1922
            $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
1923
            $date_lim_reglement = dol_print_date($line->date_lim_reglement, '%Y%m%d');
1924
1925
            $tab = array();
1926
1927
            // TYPE
1928
            $type_enregistrement = 'E'; // For write movement
1929
            $tab[] = $type_enregistrement;
1930
            // JNAL
1931
            $tab[] = substr($line->code_journal, 0, 2);
1932
            // NECR
1933
            $tab[] = $line->id;
1934
            // NPIE
1935
            $tab[] = $line->piece_num;
1936
            // DATP
1937
            $tab[] = $date_document;
1938
            // LIBE
1939
            $tab[] = $line->label_operation;
1940
            // DATH
1941
            $tab[] = $date_lim_reglement;
1942
            // CNPI
1943
            if ($line->doc_type == 'supplier_invoice') {
1944
                if (($line->debit - $line->credit) > 0) {
1945
                    $nature_piece = 'AF';
1946
                } else {
1947
                    $nature_piece = 'FF';
1948
                }
1949
            } elseif ($line->doc_type == 'customer_invoice') {
1950
                if (($line->debit - $line->credit) < 0) {
1951
                    $nature_piece = 'AC';
1952
                } else {
1953
                    $nature_piece = 'FC';
1954
                }
1955
            } else {
1956
                $nature_piece = '';
1957
            }
1958
            $tab[] = $nature_piece;
1959
            // RACI
1960
            //          if (!empty($line->subledger_account)) {
1961
            //              if ($line->doc_type == 'supplier_invoice') {
1962
            //                  $racine_subledger_account = '40';
1963
            //              } elseif ($line->doc_type == 'customer_invoice') {
1964
            //                  $racine_subledger_account = '41';
1965
            //              } else {
1966
            //                  $racine_subledger_account = '';
1967
            //              }
1968
            //          } else {
1969
            $racine_subledger_account = ''; // for records of type E leave this field blank
1970
            //          }
1971
1972
            $tab[] = $racine_subledger_account; // deprecated CPTG & CPTA use instead
1973
            // MONT
1974
            $tab[] = price(abs($line->debit - $line->credit), 0, '', 1, 2, 2);
1975
            // CODC
1976
            $tab[] = $line->sens;
1977
            // CPTG
1978
            $tab[] = length_accountg($line->numero_compte);
1979
            // DATE
1980
            $tab[] = $date_creation;
1981
            // CLET
1982
            $tab[] = $line->lettering_code;
1983
            // DATL
1984
            $tab[] = $line->date_lettering;
1985
            // CPTA
1986
            if (!empty($line->subledger_account)) {
1987
                $tab[] = length_accounta($line->subledger_account);
1988
            } else {
1989
                $tab[] = "";
1990
            }
1991
            // C.N.A.T
1992
            if ($line->doc_type == 'supplier_invoice' && !empty($line->subledger_account)) {
1993
                $tab[] = 'F';
1994
            } elseif ($line->doc_type == 'customer_invoice' && !empty($line->subledger_account)) {
1995
                $tab[] = 'C';
1996
            } else {
1997
                $tab[] = "";
1998
            }
1999
            // SECT
2000
            $tab[] = "";
2001
            // CTRE
2002
            $tab[] = "";
2003
            // NORL
2004
            $tab[] = "";
2005
            // DATV
2006
            $tab[] = "";
2007
            // REFD
2008
            $tab[] = $line->doc_ref;
2009
            // CODH
2010
            $tab[] = "";
2011
            // NSEQ
2012
            $tab[] = "";
2013
            // MTDV
2014
            $tab[] = '0';
2015
            // CODV
2016
            $tab[] = "";
2017
            // TXDV
2018
            $tab[] = '0';
2019
            // MOPM
2020
            $tab[] = "";
2021
            // BONP
2022
            $tab[] =  "";
2023
            // BQAF
2024
            $tab[] = "";
2025
            // ECES
2026
            $tab[] = "";
2027
            // TXTL
2028
            $tab[] = "";
2029
            // ECRM
2030
            $tab[] = "";
2031
            // DATK
2032
            $tab[] = "";
2033
            // HEUK
2034
            $tab[] = "";
2035
2036
            $output = implode($separator, $tab) . $end_line;
2037
            if ($exportFile) {
2038
                fwrite($exportFile, $output);
2039
            } else {
2040
                print $output;
2041
            }
2042
        }
2043
    }
2044
2045
    /**
2046
     * Export format : LD Compta version 10 & higher
2047
     * Last review for this format : 08-15-2021 Alexandre Spangaro ([email protected])
2048
     *
2049
     * Help : http://www.ldsysteme.fr/fileadmin/telechargement/np/ldcompta/Documentation/IntCptW10.pdf
2050
     *
2051
     * @param   array       $objectLines            data
2052
     * @param   resource    $exportFile             [=null] File resource to export or print if null
2053
     * @return  void
2054
     */
2055
    public function exportLDCompta10($objectLines, $exportFile = null)
2056
    {
2057
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/company.lib.php';
2058
2059
        $separator = ';';
2060
        $end_line = "\r\n";
2061
        $last_codeinvoice = '';
2062
2063
        foreach ($objectLines as $line) {
2064
            // TYPE C
2065
            if ($last_codeinvoice != $line->doc_ref) {
2066
                //recherche societe en fonction de son code client
2067
                $sql = "SELECT code_client, fk_forme_juridique, nom, address, zip, town, fk_pays, phone, siret FROM " . MAIN_DB_PREFIX . "societe";
2068
                $sql .= " WHERE code_client = '" . $this->db->escape($line->thirdparty_code) . "'";
2069
                $resql = $this->db->query($sql);
2070
2071
                if ($resql && $this->db->num_rows($resql) > 0) {
2072
                    $soc = $this->db->fetch_object($resql);
2073
2074
                    $address = array('', '', '');
2075
                    if (strpos($soc->address, "\n") !== false) {
2076
                        $address = explode("\n", $soc->address);
2077
                        if (is_array($address) && count($address) > 0) {
2078
                            foreach ($address as $key => $data) {
2079
                                $address[$key] = str_replace(array("\t", "\n", "\r"), "", $data);
2080
                                $address[$key] = dol_trunc($address[$key], 40, 'right', 'UTF-8', 1);
2081
                            }
2082
                        }
2083
                    } else {
2084
                        $address[0] = substr(str_replace(array("\t", "\r"), " ", $soc->address), 0, 40);
2085
                        $address[1] = substr(str_replace(array("\t", "\r"), " ", $soc->address), 41, 40);
2086
                        $address[2] = substr(str_replace(array("\t", "\r"), " ", $soc->address), 82, 40);
2087
                    }
2088
2089
                    $tab = array();
2090
2091
                    $type_enregistrement = 'C';
2092
                    //TYPE
2093
                    $tab[] = $type_enregistrement;
2094
                    //NOCL
2095
                    $tab[] = $soc->code_client;
2096
                    //NMCM
2097
                    $tab[] = "";
2098
                    //LIBI
2099
                    $tab[] = "";
2100
                    //TITR
2101
                    $tab[] = "";
2102
                    //RSSO
2103
                    $tab[] = $soc->nom;
2104
                    //CAD1
2105
                    $tab[] = $address[0];
2106
                    //CAD2
2107
                    $tab[] = $address[1];
2108
                    //CAD3
2109
                    $tab[] = $address[2];
2110
                    //COPO
2111
                    $tab[] = $soc->zip;
2112
                    //BUDI
2113
                    $tab[] = substr($soc->town, 0, 40);
2114
                    //CPAY
2115
                    $tab[] = "";
2116
                    //PAYS
2117
                    $tab[] = substr(getCountry($soc->fk_pays), 0, 40);
2118
                    //NTEL
2119
                    $tab[] = $soc->phone;
2120
                    //TLEX
2121
                    $tab[] = "";
2122
                    //TLPO
2123
                    $tab[] = "";
2124
                    //TLCY
2125
                    $tab[] = "";
2126
                    //NINT
2127
                    $tab[] = "";
2128
                    //COMM
2129
                    $tab[] = "";
2130
                    //SIRE
2131
                    $tab[] = str_replace(" ", "", $soc->siret);
2132
                    //RIBP
2133
                    $tab[] = "";
2134
                    //DOBQ
2135
                    $tab[] = "";
2136
                    //IBBQ
2137
                    $tab[] = "";
2138
                    //COBQ
2139
                    $tab[] = "";
2140
                    //GUBQ
2141
                    $tab[] = "";
2142
                    //CPBQ
2143
                    $tab[] = "";
2144
                    //CLBQ
2145
                    $tab[] = "";
2146
                    //BIBQ
2147
                    $tab[] = "";
2148
                    //MOPM
2149
                    $tab[] = "";
2150
                    //DJPM
2151
                    $tab[] = "";
2152
                    //DMPM
2153
                    $tab[] = "";
2154
                    //REFM
2155
                    $tab[] = "";
2156
                    //SLVA
2157
                    $tab[] = "";
2158
                    //PLCR
2159
                    $tab[] = "";
2160
                    //ECFI
2161
                    $tab[] = "";
2162
                    //CREP
2163
                    $tab[] = "";
2164
                    //NREP
2165
                    $tab[] = "";
2166
                    //TREP
2167
                    $tab[] = "";
2168
                    //MREP
2169
                    $tab[] = "";
2170
                    //GRRE
2171
                    $tab[] = "";
2172
                    //LTTA
2173
                    $tab[] = "";
2174
                    //CACT
2175
                    $tab[] = "";
2176
                    //CODV
2177
                    $tab[] = "";
2178
                    //GRTR
2179
                    $tab[] = "";
2180
                    //NOFP
2181
                    $tab[] = "";
2182
                    //BQAF
2183
                    $tab[] = "";
2184
                    //BONP
2185
                    $tab[] = "";
2186
                    //CESC
2187
                    $tab[] = "";
2188
2189
                    $output = implode($separator, $tab) . $end_line;
2190
                    if ($exportFile) {
2191
                        fwrite($exportFile, $output);
2192
                    } else {
2193
                        print $output;
2194
                    }
2195
                }
2196
            }
2197
2198
            $tab = array();
2199
2200
            $date_document = dol_print_date($line->doc_date, '%Y%m%d');
2201
            $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
2202
            $date_lim_reglement = dol_print_date($line->date_lim_reglement, '%Y%m%d');
2203
2204
            // TYPE E
2205
            $type_enregistrement = 'E'; // For write movement
2206
            $tab[] = $type_enregistrement;
2207
            // JNAL
2208
            $tab[] = substr($line->code_journal, 0, 2);
2209
            // NECR
2210
            $tab[] = $line->id;
2211
            // NPIE
2212
            $tab[] = $line->piece_num;
2213
            // DATP
2214
            $tab[] = $date_document;
2215
            // LIBE
2216
            $tab[] = dol_trunc($line->label_operation, 25, 'right', 'UTF-8', 1);
2217
            // DATH
2218
            $tab[] = $date_lim_reglement;
2219
            // CNPI
2220
            if ($line->doc_type == 'supplier_invoice') {
2221
                if (($line->amount) < 0) {      // Currently, only the sign of amount allows to know the type of invoice (standard or credit note). Other solution is to analyse debit/credit/role of account. TODO Add column doc_type_long or make amount mandatory with rule on sign.
2222
                    $nature_piece = 'AF';
2223
                } else {
2224
                    $nature_piece = 'FF';
2225
                }
2226
            } elseif ($line->doc_type == 'customer_invoice') {
2227
                if (($line->amount) < 0) {
2228
                    $nature_piece = 'AC';       // Currently, only the sign of amount allows to know the type of invoice (standard or credit note). Other solution is to analyse debit/credit/role of account. TODO Add column doc_type_long or make amount mandatory with rule on sign.
2229
                } else {
2230
                    $nature_piece = 'FC';
2231
                }
2232
            } else {
2233
                $nature_piece = '';
2234
            }
2235
            $tab[] = $nature_piece;
2236
            // RACI
2237
            //          if (!empty($line->subledger_account)) {
2238
            //              if ($line->doc_type == 'supplier_invoice') {
2239
            //                  $racine_subledger_account = '40';
2240
            //              } elseif ($line->doc_type == 'customer_invoice') {
2241
            //                  $racine_subledger_account = '41';
2242
            //              } else {
2243
            //                  $racine_subledger_account = '';
2244
            //              }
2245
            //          } else {
2246
            $racine_subledger_account = ''; // for records of type E leave this field blank
2247
            //          }
2248
2249
            $tab[] = $racine_subledger_account; // deprecated CPTG & CPTA use instead
2250
            // MONT
2251
            $tab[] = price(abs($line->debit - $line->credit), 0, '', 1, 2);
2252
            // CODC
2253
            $tab[] = $line->sens;
2254
            // CPTG
2255
            $tab[] = length_accountg($line->numero_compte);
2256
            // DATE
2257
            $tab[] = $date_document;
2258
            // CLET
2259
            $tab[] = $line->lettering_code;
2260
            // DATL
2261
            $tab[] = $line->date_lettering;
2262
            // CPTA
2263
            if (!empty($line->subledger_account)) {
2264
                $tab[] = length_accounta($line->subledger_account);
2265
            } else {
2266
                $tab[] = "";
2267
            }
2268
            // C.N.A.T
2269
            if ($line->doc_type == 'supplier_invoice' && !empty($line->subledger_account)) {
2270
                $tab[] = 'F';
2271
            } elseif ($line->doc_type == 'customer_invoice' && !empty($line->subledger_account)) {
2272
                $tab[] = 'C';
2273
            } else {
2274
                $tab[] = "";
2275
            }
2276
            // CTRE
2277
            $tab[] = "";
2278
            // NORL
2279
            $tab[] = "";
2280
            // DATV
2281
            $tab[] = "";
2282
            // REFD
2283
            $tab[] = $line->doc_ref;
2284
            // NECA
2285
            $tab[] = '0';
2286
            // CSEC
2287
            $tab[] = "";
2288
            // CAFF
2289
            $tab[] = "";
2290
            // CDES
2291
            $tab[] = "";
2292
            // QTUE
2293
            $tab[] = "";
2294
            // MTDV
2295
            $tab[] = '0';
2296
            // CODV
2297
            $tab[] = "";
2298
            // TXDV
2299
            $tab[] = '0';
2300
            // MOPM
2301
            $tab[] = "";
2302
            // BONP
2303
            $tab[] = "";
2304
            // BQAF
2305
            $tab[] = "";
2306
            // ECES
2307
            $tab[] = "";
2308
            // TXTL
2309
            $tab[] = "";
2310
            // ECRM
2311
            $tab[] = "";
2312
            // DATK
2313
            $tab[] = "";
2314
            // HEUK
2315
            $tab[] = "";
2316
2317
            $output = implode($separator, $tab) . $end_line;
2318
            if ($exportFile) {
2319
                fwrite($exportFile, $output);
2320
            } else {
2321
                print $output;
2322
            }
2323
2324
            $last_codeinvoice = $line->doc_ref;
2325
        }
2326
    }
2327
2328
    /**
2329
     * Export format : Charlemagne
2330
     *
2331
     * @param   array       $objectLines            data
2332
     * @param   resource    $exportFile             [=null] File resource to export or print if null
2333
     * @return  void
2334
     */
2335
    public function exportCharlemagne($objectLines, $exportFile = null)
2336
    {
2337
        global $langs;
2338
        $langs->load('compta');
2339
2340
        $separator = "\t";
2341
        $end_line = "\n";
2342
2343
        $tab = array();
2344
2345
        $tab[] = $langs->transnoentitiesnoconv('Date');
2346
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Journal'), 6);
2347
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Account'), 15);
2348
        $tab[] = self::trunc($langs->transnoentitiesnoconv('LabelAccount'), 60);
2349
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Piece'), 20);
2350
        $tab[] = self::trunc($langs->transnoentitiesnoconv('LabelOperation'), 60);
2351
        $tab[] = $langs->transnoentitiesnoconv('Amount');
2352
        $tab[] = 'S';
2353
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Analytic') . ' 1', 15);
2354
        $tab[] = self::trunc($langs->transnoentitiesnoconv('AnalyticLabel') . ' 1', 60);
2355
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Analytic') . ' 2', 15);
2356
        $tab[] = self::trunc($langs->transnoentitiesnoconv('AnalyticLabel') . ' 2', 60);
2357
        $tab[] = self::trunc($langs->transnoentitiesnoconv('Analytic') . ' 3', 15);
2358
        $tab[] = self::trunc($langs->transnoentitiesnoconv('AnalyticLabel') . ' 3', 60);
2359
2360
        $output = implode($separator, $tab) . $end_line;
2361
        if ($exportFile) {
2362
            fwrite($exportFile, $output);
2363
        } else {
2364
            print $output;
2365
        }
2366
2367
        foreach ($objectLines as $line) {
2368
            $date_document = dol_print_date($line->doc_date, '%Y%m%d');
2369
2370
            $tab = array();
2371
2372
            $tab[] = $date_document; //Date
2373
2374
            $tab[] = self::trunc($line->code_journal, 6); //Journal code
2375
2376
            if (!empty($line->subledger_account)) {
2377
                $account = $line->subledger_account;
2378
            } else {
2379
                $account = $line->numero_compte;
2380
            }
2381
            $tab[] = self::trunc($account, 15); //Account number
2382
2383
            $tab[] = self::trunc($line->label_compte, 60); //Account label
2384
            $tab[] = self::trunc($line->doc_ref, 20); //Piece
2385
            // Clean label operation to prevent problem on export with tab separator & other character
2386
            $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
2387
            $tab[] = self::trunc($line->label_operation, 60); //Operation label
2388
            $tab[] = price(abs($line->debit - $line->credit)); //Amount
2389
            $tab[] = $line->sens; //Direction
2390
            $tab[] = ""; //Analytic
2391
            $tab[] = ""; //Analytic
2392
            $tab[] = ""; //Analytic
2393
            $tab[] = ""; //Analytic
2394
            $tab[] = ""; //Analytic
2395
            $tab[] = ""; //Analytic
2396
2397
            $output = implode($separator, $tab) . $end_line;
2398
            if ($exportFile) {
2399
                fwrite($exportFile, $output);
2400
            } else {
2401
                print $output;
2402
            }
2403
        }
2404
    }
2405
2406
    /**
2407
     * Export format : Gestimum V3
2408
     *
2409
     * @param   array       $objectLines            data
2410
     * @param   resource    $exportFile             [=null] File resource to export or print if null
2411
     * @return  void
2412
     */
2413
    public function exportGestimumV3($objectLines, $exportFile = null)
2414
    {
2415
        global $langs;
2416
2417
        $separator = ',';
2418
        $end_line = "\r\n";
2419
2420
        $invoices_infos = array();
2421
        $supplier_invoices_infos = array();
2422
        foreach ($objectLines as $line) {
2423
            if ($line->debit == 0 && $line->credit == 0) {
2424
                //unset($array[$line]);
2425
            } else {
2426
                $date_document = dol_print_date($line->doc_date, '%d/%m/%Y');
2427
                $date_echeance = dol_print_date($line->date_lim_reglement, '%Y%m%d');
2428
2429
                $invoice_ref = $line->doc_ref;
2430
                $company_name = "";
2431
2432
                if (($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice') && $line->fk_doc > 0) {
2433
                    if (
2434
                        ($line->doc_type == 'customer_invoice' && !isset($invoices_infos[$line->fk_doc])) ||
2435
                        ($line->doc_type == 'supplier_invoice' && !isset($supplier_invoices_infos[$line->fk_doc]))
2436
                    ) {
2437
                        if ($line->doc_type == 'customer_invoice') {
2438
                            // Get new customer invoice ref and company name
2439
                            $sql = 'SELECT f.ref, s.nom FROM ' . MAIN_DB_PREFIX . 'facture as f';
2440
                            $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe AS s ON f.fk_soc = s.rowid';
2441
                            $sql .= ' WHERE f.rowid = ' . ((int) $line->fk_doc);
2442
                            $resql = $this->db->query($sql);
2443
                            if ($resql) {
2444
                                if ($obj = $this->db->fetch_object($resql)) {
2445
                                    // Save invoice infos
2446
                                    $invoices_infos[$line->fk_doc] = array('ref' => $obj->ref, 'company_name' => $obj->nom);
2447
                                    $invoice_ref = $obj->ref;
2448
                                    $company_name = $obj->nom;
2449
                                }
2450
                            }
2451
                        } else {
2452
                            // Get new supplier invoice ref and company name
2453
                            $sql = 'SELECT ff.ref, s.nom FROM ' . MAIN_DB_PREFIX . 'facture_fourn as ff';
2454
                            $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe AS s ON ff.fk_soc = s.rowid';
2455
                            $sql .= ' WHERE ff.rowid = ' . ((int) $line->fk_doc);
2456
                            $resql = $this->db->query($sql);
2457
                            if ($resql) {
2458
                                if ($obj = $this->db->fetch_object($resql)) {
2459
                                    // Save invoice infos
2460
                                    $supplier_invoices_infos[$line->fk_doc] = array('ref' => $obj->ref, 'company_name' => $obj->nom);
2461
                                    $invoice_ref = $obj->ref;
2462
                                    $company_name = $obj->nom;
2463
                                }
2464
                            }
2465
                        }
2466
                    } elseif ($line->doc_type == 'customer_invoice') {
2467
                        // Retrieve invoice infos
2468
                        $invoice_ref = $invoices_infos[$line->fk_doc]['ref'];
2469
                        $company_name = $invoices_infos[$line->fk_doc]['company_name'];
2470
                    } else {
2471
                        // Retrieve invoice infos
2472
                        $invoice_ref = $supplier_invoices_infos[$line->fk_doc]['ref'];
2473
                        $company_name = $supplier_invoices_infos[$line->fk_doc]['company_name'];
2474
                    }
2475
                }
2476
2477
                $tab = array();
2478
2479
                $tab[] = $line->id;
2480
                $tab[] = $date_document;
2481
                $tab[] = substr($line->code_journal, 0, 4);
2482
2483
                if ((substr($line->numero_compte, 0, 3) == '411') || (substr($line->numero_compte, 0, 3) == '401')) {
2484
                    $tab[] = length_accountg($line->subledger_account);
2485
                } else {
2486
                    $tab[] = substr(length_accountg($line->numero_compte), 0, 15);
2487
                }
2488
                //Libellé Auto
2489
                $tab[] = "";
2490
                //print '"'.dol_trunc(str_replace('"', '', $line->label_operation),40,'right','UTF-8',1).'"';
2491
                //Libellé manual
2492
                $tab[] = dol_trunc(str_replace('"', '', $invoice_ref . (!empty($company_name) ? ' - ' : '') . $company_name), 40, 'right', 'UTF-8', 1);
2493
                //Numéro de pièce
2494
                $tab[] = dol_trunc(str_replace('"', '', $line->piece_num), 10, 'right', 'UTF-8', 1);
2495
                //Devise
2496
                $tab[] = 'EUR';
2497
                //Amount
2498
                $tab[] = price2num(abs($line->debit - $line->credit));
2499
                //Sens
2500
                $tab[] = $line->sens;
2501
                //Code lettrage
2502
                $tab[] = "";
2503
                //Date Echéance
2504
                $tab[] = $date_echeance;
2505
2506
                $output = implode($separator, $tab) . $end_line;
2507
                if ($exportFile) {
2508
                    fwrite($exportFile, $output);
2509
                } else {
2510
                    print $output;
2511
                }
2512
            }
2513
        }
2514
    }
2515
2516
    /**
2517
     * Export format : Gestimum V5
2518
     *
2519
     * @param   array       $objectLines            data
2520
     * @param   resource    $exportFile             [=null] File resource to export or print if null
2521
     * @return  void
2522
     */
2523
    public function exportGestimumV5($objectLines, $exportFile = null)
2524
    {
2525
        $separator = ',';
2526
        $end_line = "\r\n";
2527
2528
        foreach ($objectLines as $line) {
2529
            if ($line->debit == 0 && $line->credit == 0) {
2530
                //unset($array[$line]);
2531
            } else {
2532
                $date_document = dol_print_date($line->doc_date, '%d%m%Y');
2533
2534
                $tab = array();
2535
2536
                $tab[] = $line->id;
2537
                $tab[] = $date_document;
2538
                $tab[] = substr($line->code_journal, 0, 4);
2539
                if ((substr($line->numero_compte, 0, 3) == '411') || (substr($line->numero_compte, 0, 3) == '401')) {   // TODO No hard code value
2540
                    $tab[] = length_accountg($line->subledger_account);
2541
                } else {
2542
                    $tab[] = substr(length_accountg($line->numero_compte), 0, 15);
2543
                }
2544
                $tab[] = "";
2545
                $tab[] = '"' . dol_trunc(str_replace('"', '', $line->label_operation), 40, 'right', 'UTF-8', 1) . '"';
2546
                $tab[] = '"' . dol_trunc(str_replace('"', '', $line->doc_ref), 40, 'right', 'UTF-8', 1) . '"';
2547
                $tab[] = '"' . dol_trunc(str_replace('"', '', $line->piece_num), 10, 'right', 'UTF-8', 1) . '"';
2548
                $tab[] = price2num(abs($line->debit - $line->credit));
2549
                $tab[] = $line->sens;
2550
                $tab[] = $date_document;
2551
                $tab[] = "";
2552
                $tab[] = "";
2553
                $tab[] = 'EUR';
2554
2555
                $output = implode($separator, $tab) . $end_line;
2556
                if ($exportFile) {
2557
                    fwrite($exportFile, $output);
2558
                } else {
2559
                    print $output;
2560
                }
2561
            }
2562
        }
2563
    }
2564
2565
    /**
2566
    * Export format : iSuite Expert
2567
    *
2568
    * by OpenSolus [https://opensolus.fr]
2569
    *
2570
     * @param   array       $objectLines            data
2571
     * @param   resource    $exportFile             [=null] File resource to export or print if null
2572
     * @return  void
2573
    */
2574
    public function exportiSuiteExpert($objectLines, $exportFile = null)
2575
    {
2576
        $separator = ';';
2577
        $end_line = "\r\n";
2578
2579
2580
        foreach ($objectLines as $line) {
2581
            $tab = array();
2582
2583
            $date = dol_print_date($line->doc_date, '%d/%m/%Y');
2584
2585
            $tab[] = $line->piece_num;
2586
            $tab[] = $date;
2587
            $tab[] = substr($date, 6, 4);
2588
            $tab[] = substr($date, 3, 2);
2589
            $tab[] = substr($date, 0, 2);
2590
            $tab[] = $line->doc_ref;
2591
            //Conversion de chaine UTF8 en Latin9
2592
            $tab[] = mb_convert_encoding(str_replace(' - Compte auxiliaire', '', $line->label_operation), "Windows-1252", 'UTF-8');
2593
2594
            //Calcul de la longueur des numéros de comptes
2595
            $taille_numero = strlen(length_accountg($line->numero_compte));
2596
2597
            //Création du numéro de client et fournisseur générique
2598
            $numero_cpt_client = '411';
2599
            $numero_cpt_fourn = '401';
2600
            for ($i = 1; $i <= ($taille_numero - 3); $i++) {
2601
                $numero_cpt_client .= '0';
2602
                $numero_cpt_fourn .= '0';
2603
            }
2604
2605
            //Création des comptes auxiliaire des clients et fournisseur
2606
            if (length_accountg($line->numero_compte) == $numero_cpt_client || length_accountg($line->numero_compte) == $numero_cpt_fourn) {
2607
                $tab[] = rtrim(length_accounta($line->subledger_account), "0");
2608
            } else {
2609
                $tab[] = length_accountg($line->numero_compte);
2610
            }
2611
            $nom_client = explode(" - ", $line->label_operation);
2612
            $tab[] = mb_convert_encoding($nom_client[0], "Windows-1252", 'UTF-8');
2613
            $tab[] = price($line->debit);
2614
            $tab[] = price($line->credit);
2615
            $tab[] = price($line->montant);
2616
            $tab[] = $line->code_journal;
2617
2618
            $output = implode($separator, $tab) . $end_line;
2619
            if ($exportFile) {
2620
                fwrite($exportFile, $output);
2621
            } else {
2622
                print $output;
2623
            }
2624
        }
2625
    }
2626
2627
    /**
2628
     * trunc
2629
     *
2630
     * @param string    $str    String
2631
     * @param integer   $size   Data to trunc
2632
     * @return string
2633
     */
2634
    public static function trunc($str, $size)
2635
    {
2636
        return dol_trunc($str, $size, 'right', 'UTF-8', 1);
2637
    }
2638
2639
    /**
2640
     * toAnsi
2641
     *
2642
     * @param string    $str        Original string to encode and optionally truncate
2643
     * @param integer   $size       Truncate string after $size characters
2644
     * @return string               String encoded in Windows-1251 charset
2645
     */
2646
    public static function toAnsi($str, $size = -1)
2647
    {
2648
        $retVal = dol_string_nohtmltag($str, 1, 'Windows-1251');
2649
        if ($retVal >= 0 && $size >= 0) {
2650
            $retVal = dol_substr($retVal, 0, $size, 'Windows-1251');
2651
        }
2652
        return $retVal;
2653
    }
2654
}
2655