Test Failed
Branch main (fda838)
by Rafael
50:22
created

AccountancyExport::exportSAGE50SWISS()   F

Complexity

Conditions 24
Paths 3074

Size

Total Lines 143
Code Lines 95

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 24
eloc 95
nc 3074
nop 2
dl 0
loc 143
rs 0
c 1
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-2023  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 DoliModules\Accounting\Model;
36
37
/**
38
 * \file        htdocs/accountancy/class/accountancyexport.class.php
39
 * \ingroup     Accountancy (Double entries)
40
 * \brief       Class accountancy export
41
 */
42
43
use DoliCore\Base\Model;
44
45
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
46
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
47
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
48
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
49
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
50
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
51
52
/**
53
 * Manage the different format accountancy export
54
 */
55
class AccountancyExport extends Model
0 ignored issues
show
Deprecated Code introduced by
The class DoliCore\Base\Model has been deprecated: This class is only needed for compatibility with Dolibarr. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

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