Passed
Push — main ( 01772d...cee9ce )
by Daniel
15:10 queued 12:02
created

setStandardizedFeedbackArray()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 63
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
cc 6
eloc 55
c 5
b 0
f 1
nc 6
nop 1
dl 0
loc 63
rs 8.3595

How to fix   Long Method   

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) 2024, Daniel Popiniuc and its licensors.
5
 *
6
 * All rights reserved. This program and the accompanying materials
7
 * are made available under the terms of the Eclipse Public License v1.0
8
 * which accompanies this distribution, and is available at
9
 * http://www.eclipse.org/legal/epl-v20.html
10
 *
11
 * Contributors:
12
 *    Daniel Popiniuc
13
 */
14
15
namespace danielgp\efactura;
16
17
trait TraitUserInterfaceLogic
18
{
19
20
    use \danielgp\io_operations\InputOutputFiles;
21
22
    protected array $arrayConfiguration;
23
    protected $translation;
24
25
    public function actionAnalyzeZIPfromANAFfromLocalFolder(string $strFilePath): array
26
    {
27
        $arrayFiles    = new \RecursiveDirectoryIterator($strFilePath, \FilesystemIterator::SKIP_DOTS);
28
        $arrayInvoices = [];
29
        $intFileNo     = 0;
30
        foreach ($arrayFiles as $strFile) {
31
            if ($strFile->isFile()) {
32
                $arrayFileDetails = $this->handleResponseFile($strFile);
33
                if ($arrayFileDetails !== []) {
34
                    $arrayInvoices[$intFileNo] = $arrayFileDetails;
35
                    $intFileNo++;
36
                }
37
            }
38
        }
39
        return $arrayInvoices;
40
    }
41
42
    protected function getConfiguration()
43
    {
44
        $this->arrayConfiguration = $this->getArrayFromJsonFile(__DIR__
45
            . DIRECTORY_SEPARATOR . 'config', 'BasicConfiguration.json');
46
    }
47
48
    /**
49
     * Archived document is read as content in memory since 2024-02-16
50
     * (prior to this date a temporary local file was saved, processed and finally removed when done with it)
51
     *
52
     * @param array $arrayData
53
     * @return array
54
     */
55
    private function getDocumentDetails(array $arrayData): array
56
    {
57
        $appR               = new \danielgp\efactura\ClassElectronicInvoiceRead();
58
        $arrayElectronicInv = $appR->readElectronicInvoice($arrayData['strInvoiceContent']);
59
        $arrayBasic         = $arrayElectronicInv['Header']['CommonBasicComponents-2'];
60
        $arrayAggregate     = $arrayElectronicInv['Header']['CommonAggregateComponents-2'];
61
        $arrayStandardized  = [
62
            'Customer'             => $arrayAggregate['AccountingCustomerParty']['Party'],
63
            'ID'                   => $arrayBasic['ID'],
64
            'IssueDate'            => $arrayBasic['IssueDate'],
65
            'DocumentCurrencyCode' => $arrayBasic['DocumentCurrencyCode'],
66
            'No_of_Lines'          => count($arrayElectronicInv['Lines']),
67
            'Supplier'             => $arrayAggregate['AccountingSupplierParty']['Party'],
68
            'TOTAL'                => (float) $arrayAggregate['LegalMonetaryTotal']['TaxInclusiveAmount']['value'],
69
            'wo_VAT'               => (float) $arrayAggregate['LegalMonetaryTotal']['TaxExclusiveAmount']['value'],
70
        ];
71
        return $arrayStandardized;
72
    }
73
74
    private function handleResponseFile(\SplFileInfo|string $strFile): array
75
    {
76
        $arrayToReturn = [];
77
        $strFileMime   = mime_content_type($strFile->getRealPath());
78
        switch ($strFileMime) {
79
            case 'application/json':
80
                $arrayError    = $this->getArrayFromJsonFile($strFile->getPath(), $strFile->getFilename());
81
                $arrayToReturn = $this->setStandardizedFeedbackArray([
82
                    'Error'          => $arrayError['eroare'] . ' ===> ' . $arrayError['titlu'],
83
                    'Response_Index' => $strFile->getFilename(),
84
                    'Response_Size'  => $strFile->getSize(),
85
                ]);
86
                break;
87
            case 'application/zip':
88
                $arrayToReturn = $this->setArchiveFromAnaf($strFile->getRealPath(), $strFile->getSize());
89
                break;
90
        }
91
        return $arrayToReturn;
92
    }
93
94
    private function handleArchiveContent(\ZipArchive $classZip, array $arrayArchiveParam): array
95
    {
96
        $arrayToReturn = [];
97
        for ($intArchivedFile = 0; $intArchivedFile < $arrayArchiveParam['No_of_Files']; $intArchivedFile++) {
98
            $strArchivedFile = $classZip->getNameIndex($intArchivedFile);
99
            $matches         = [];
100
            preg_match('/^[0-9]{5,20}\.xml$/', $strArchivedFile, $matches, PREG_OFFSET_CAPTURE);
101
            $matches2        = [];
102
            preg_match('/^semnatura_[0-9]{5,20}\.xml$/', $strArchivedFile, $matches2, PREG_OFFSET_CAPTURE);
103
            if ($matches !== []) {
104
                $resInvoice        = $classZip->getStream($strArchivedFile);
105
                $strInvoiceContent = stream_get_contents($resInvoice);
106
                fclose($resInvoice);
107
                $strFileStats      = $classZip->statIndex($intArchivedFile);
108
                $arrayToReturn     = $this->setStandardizedFeedbackArray([
109
                    'Response_Index'      => pathinfo($arrayArchiveParam['FileName'])['filename'],
110
                    'Size'                => $strFileStats['size'],
111
                    'FileDateTime'        => date('Y-m-d H:i:s', $strFileStats['mtime']),
112
                    'Matches'             => $matches,
113
                    'strArchivedFileName' => $strArchivedFile,
114
                    'strInvoiceContent'   => $strInvoiceContent,
115
                    'Response_Size'       => $arrayArchiveParam['Response_Size'],
116
                ]);
117
            } elseif ($matches2 === []) {
118
                echo vsprintf('<div>' . $this->arrayConfiguration['Feedback']['DifferentFile'] . '</div>', [
119
                    $strArchivedFile,
120
                    $strFile->getBasename(),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $strFile does not exist. Did you maybe mean $strFileStats?
Loading history...
121
                ]);
122
            }
123
        }
124
        return $arrayToReturn;
125
    }
126
127
    private function setArchiveFromAnaf(string $strFile, int $intFileSize)
128
    {
129
        $arrayToReturn = [];
130
        $classZip      = new \ZipArchive();
131
        $res           = $classZip->open($strFile, \ZipArchive::RDONLY);
132
        if ($res) {
133
            $intFilesArchived = $classZip->numFiles;
134
            $arrayToReturn    = $this->handleArchiveContent($classZip, [
135
                'No_of_Files'   => $intFilesArchived,
136
                'FileName'      => $strFile,
137
                'Response_Size' => $intFileSize,
138
            ]);
139
        } else {
140
            // @codeCoverageIgnoreStart
141
            $arrayToReturn = $this->setStandardizedFeedbackArray([
142
                'Response_Index' => pathinfo($strFile)['filename'],
143
                'Error'          => $this->translation->find(null, 'i18n_Msg_InvalidZip')->getTranslation(),
144
                'Response_Size'  => 0,
145
            ]);
146
            // @codeCoverageIgnoreEnd
147
        }
148
        return $arrayToReturn;
149
    }
150
151
    private function setDataSupplierOrCustomer(array $arrayData)
152
    {
153
        $strCustomerCui = '';
154
        if (isset($arrayData['PartyTaxScheme']['01']['CompanyID'])) {
155
            $strCustomerCui = $arrayData['PartyTaxScheme']['01']['CompanyID'];
156
        } else {
157
            $strCustomerCui = $arrayData['PartyLegalEntity']['CompanyID'];
158
        }
159
        if (is_numeric($strCustomerCui)) {
160
            $strCustomerCui = 'RO' . $strCustomerCui;
161
        }
162
        return $strCustomerCui;
163
    }
164
165
    private function setDaysElapsed(string $strFirstDate, string $strLaterDate): string
166
    {
167
        $origin   = new \DateTimeImmutable($strFirstDate);
168
        $target   = new \DateTimeImmutable($strLaterDate);
169
        $interval = $origin->diff($target);
170
        return $interval->format('%R%a');
171
    }
172
173
    private function setDefaultsToInvoiceDetailsArray(array $arrayData): array
174
    {
175
        return [
176
            'Response_DateTime'    => '',
177
            'Response_Index'       => $arrayData['Response_Index'],
178
            'Response_Size'        => $arrayData['Response_Size'],
179
            'Loading_Index'        => '',
180
            'Size'                 => '',
181
            'Document_No'          => '',
182
            'Issue_Date'           => '',
183
            'Issue_YearMonth'      => '',
184
            'DocumentCurrencyCode' => '',
185
            'Amount_wo_VAT'        => '',
186
            'Amount_TOTAL'         => '',
187
            'Amount_VAT'           => '',
188
            'Supplier_CUI'         => '',
189
            'Supplier_Name'        => '',
190
            'Customer_CUI'         => '',
191
            'Customer_Name'        => '',
192
            'No_of_Lines'          => '',
193
            'Error'                => '',
194
            'Mesaj_Cumparator'     => '',
195
            'Days_Between'         => '',
196
        ];
197
    }
198
199
    private function setErrorsFromExtendedMarkupLaguage(array $arrayData, string $strErrorTag): array
200
    {
201
        $arrayErrors = [];
202
        $parser      = xml_parser_create();
203
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
204
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
205
        xml_parse_into_struct($parser, $arrayData['strInvoiceContent'], $arrayErrors);
206
        xml_parser_free($parser);
207
        return [
208
            'Loading_Index'     => $arrayErrors[0]['attributes']['Index_incarcare'],
209
            'Size'              => $arrayData['Size'],
210
            'Response_DateTime' => $arrayData['FileDateTime'],
211
            'Supplier_CUI'      => 'RO' . $arrayErrors[0]['attributes']['Cif_emitent'],
212
            'Supplier_Name'     => '??????????',
213
            'Error'             => sprintf($strErrorTag, $arrayErrors[1]['attributes']['errorMessage']),
214
        ];
215
    }
216
217
    private function setLocalization(): void
218
    {
219
        if (!array_key_exists('language_COUNTRY', $_GET)) {
220
            $_GET['language_COUNTRY'] = 'ro_RO';
221
        }
222
        $loader            = new \Gettext\Loader\PoLoader();
223
        $this->translation = $loader->loadFile(__DIR__ . '/locale/' . $_GET['language_COUNTRY']
224
            . '/LC_MESSAGES/eFactura.po');
225
    }
226
227
    private function setStandardizedFeedbackArray(array $arrayData): array
228
    {
229
        $arrayToReturn = $this->setDefaultsToInvoiceDetailsArray($arrayData);
230
        $strErrorTag   = '<div style="max-width:200px;font-size:0.8rem;">%s</div>';
231
        $strTimeZone   = $this->translation->find(null, 'i18n_TimeZone')->getTranslation();
232
        $strFormatter  = new \IntlDateFormatter(
233
            $_GET['language_COUNTRY'],
234
            \IntlDateFormatter::FULL,
235
            \IntlDateFormatter::FULL,
236
            $strTimeZone,
237
            \IntlDateFormatter::GREGORIAN,
238
            'r-MM__MMMM'
239
        );
240
        if (array_key_exists('Error', $arrayData)) {
241
            $arrayToReturn['Error'] = sprintf($strErrorTag, $arrayData['Error']);
242
            $arrayToReturn['Size']  = 0;
243
        } else {
244
            $appR              = new \danielgp\efactura\ClassElectronicInvoiceRead();
245
            $objFile           = $appR->readElectronicXmlHeader($arrayData['strInvoiceContent']);
246
            $documentHeaderTag = $appR->getDocumentRoot($objFile);
247
            switch($documentHeaderTag['DocumentTagName']) {
248
                case 'header':
249
                    switch($documentHeaderTag['DocumentNameSpaces']['']) {
250
                        case 'mfp:anaf:dgti:efactura:mesajEroriFactuta:v1':
251
                            $arrayTemp     = $this->setErrorsFromExtendedMarkupLaguage($arrayData, $strErrorTag);
252
                            $arrayToReturn = array_merge($arrayToReturn, $arrayTemp);
253
                            break;
254
                        case 'mfp:anaf:dgti:spv:reqMesaj:v1':
255
                            $arrayTemp     = [
256
                                'Loading_Index'     => $documentHeaderTag['header']['index_incarcare'],
257
                                'Mesaj_Cumparator'  => $documentHeaderTag['header']['message'],
258
                                'Size'              => $arrayData['Size'],
259
                                'Response_DateTime' => $arrayData['FileDateTime'],
260
                            ];
261
                            $arrayToReturn = array_merge($arrayToReturn, $arrayTemp);
262
                            break;
263
                    }
264
                    break;
265
                case 'Invoice':
266
                    $arrayAttr     = $this->getDocumentDetails($arrayData);
267
                    $arrayTemp     = [
268
                        'Loading_Index'        => substr($arrayData['Matches'][0][0], 0, -4),
269
                        'Size'                 => $arrayData['Size'],
270
                        'Document_No'          => $arrayAttr['ID'],
271
                        'Issue_Date'           => $arrayAttr['IssueDate'],
272
                        'Issue_YearMonth'      => $strFormatter->format(new \DateTime($arrayAttr['IssueDate'])),
273
                        'Response_DateTime'    => $arrayData['FileDateTime'],
274
                        'DocumentCurrencyCode' => $arrayAttr['DocumentCurrencyCode'],
275
                        'Amount_wo_VAT'        => $arrayAttr['wo_VAT'],
276
                        'Amount_TOTAL'         => $arrayAttr['TOTAL'],
277
                        'Amount_VAT'           => round(($arrayAttr['TOTAL'] - $arrayAttr['wo_VAT']), 2),
278
                        'Supplier_CUI'         => $this->setDataSupplierOrCustomer($arrayAttr['Supplier']),
279
                        'Supplier_Name'        => $arrayAttr['Supplier']['PartyLegalEntity']['RegistrationName'],
280
                        'Customer_CUI'         => $this->setDataSupplierOrCustomer($arrayAttr['Customer']),
281
                        'Customer_Name'        => $arrayAttr['Customer']['PartyLegalEntity']['RegistrationName'],
282
                        'No_of_Lines'          => $arrayAttr['No_of_Lines'],
283
                        'Days_Between'         => $this->setDaysElapsed($arrayAttr['IssueDate'], $arrayData['FileDateTime']),
284
                    ];
285
                    $arrayToReturn = array_merge($arrayToReturn, $arrayTemp);
286
                    break;
287
            }
288
        }
289
        return $arrayToReturn;
290
    }
291
}
292