ClassElectronicInvoiceWrite::setElementComment()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.3731

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 10
ccs 5
cts 7
cp 0.7143
crap 4.3731
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Copyright (c) 2024 - 2025 Daniel Popiniuc.
5
 * All rights reserved. This program and the accompanying materials
6
 * are made available under the terms of the Eclipse Public License v1.0
7
 * which accompanies this distribution, and is available at
8
 * http://www.eclipse.org/legal/epl-v10.html
9
 *
10
 * Contributors:
11
 *    Daniel Popiniuc
12
 */
13
14
namespace danielgp\efactura;
15
16
class ClassElectronicInvoiceWrite
17
{
18
    use TraitVersions;
19
20
    protected \XMLWriter $objXmlWriter;
21
22 16
    private function setDecisionElements(array $arrayInput, string $strKey, string $strTag, string $strCategory): void
23
    {
24
        switch($strCategory) {
25 16
            case 'ElementsOrdered':
26 16
                $this->setElementsOrdered([
27 16
                    'commentParentKey' => $strKey,
28 16
                    'data'             => $arrayInput['data'][$strTag],
29 16
                    'tag'              => $strTag,
30 16
                ]);
31 16
                break;
32 16
            case 'MultipleElementsOrdered':
33 16
                $this->setMultipleElementsOrdered([
34 16
                    'commentParentKey' => $strKey,
35 16
                    'data'             => $arrayInput['data'][$strTag],
36 16
                    'tag'              => $strTag,
37 16
                ]);
38 16
                break;
39 16
            case 'SingleElementWithAttribute':
40 16
                $this->setSingleElementWithAttribute([
41 16
                    'commentParentKey' => $arrayInput['commentParentKey'],
42 16
                    'data'             => $arrayInput['data'][$strTag],
43 16
                    'tag'              => $strTag,
44 16
                ]);
45 16
                break;
46
        }
47
    }
48
49 16
    private function setElementComment(string $strKey): void
50
    {
51 16
        if (array_key_exists($strKey, $this->arraySettings['Comments'])) {
52 2
            $elementComment = $this->arraySettings['Comments'][$strKey];
53 2
            if (is_array($elementComment)) {
54
                foreach ($elementComment as $value) {
55
                    $this->objXmlWriter->writeComment($value);
56
                }
57
            } else {
58 2
                $this->objXmlWriter->writeComment($elementComment);
59
            }
60
        }
61
    }
62
63 16
    private function setElementsOrdered(array $arrayInput): void
64
    {
65 16
        $this->setElementComment($arrayInput['commentParentKey']);
66 16
        $this->objXmlWriter->startElement('cac:' . $arrayInput['tag']);
67 16
        $this->setExtraElement($arrayInput, 'Start');
68 16
        foreach ($this->arraySettings['CustomOrder'][$arrayInput['commentParentKey']] as $value) {
69 16
            if (array_key_exists($value, $arrayInput['data'])) { // because certain value are optional
70 16
                $key         = implode('_', [$arrayInput['commentParentKey'], $value]);
71 16
                $matches     = [];
72 16
                preg_match('/^.*(Amount|Quantity)$/', $value, $matches, PREG_OFFSET_CAPTURE);
73 16
                $strCategory = $this->setCategorizedVerifications([
74 16
                    'commentParentKey' => $arrayInput['commentParentKey'],
75 16
                    'data'             => $arrayInput['data'][$value],
76 16
                    'matches'          => $matches,
77 16
                    'tag'              => $value,
78 16
                ]);
79 16
                $this->setDecisionElements($arrayInput, $key, $value, $strCategory);
80
            }
81
        }
82 16
        $this->setExtraElement($arrayInput, 'End');
83 16
        $this->objXmlWriter->endElement(); // $arrayInput['tag']
84
    }
85
86 16
    private function setExtraElement(array $arrayInput, string $strType): void
87
    {
88 16
        if (in_array($arrayInput['tag'], ['AccountingCustomerParty', 'AccountingSupplierParty'])) {
89
            switch($strType) {
90 16
                case 'End':
91 16
                    $this->objXmlWriter->endElement();
92 16
                    break;
93 16
                case 'Start':
94 16
                    $this->objXmlWriter->startElement('cac:Party');
95 16
                    break;
96
            }
97
        }
98
    }
99
100 16
    private function setHeaderCommonBasicComponents(array $arrayElementWithData): void
101
    {
102 16
        $arrayCustomOrdered = $this->arraySettings['CustomOrder']['Header_CBC'];
103 16
        foreach ($arrayCustomOrdered as $value) {
104 16
            if (array_key_exists($value, $arrayElementWithData)) {
105 16
                $this->setElementComment($value);
106 16
                $this->objXmlWriter->writeElement('cbc:' . $value, $arrayElementWithData[$value]);
107
            }
108
        }
109
    }
110
111 16
    private function setMultipleElementsOrdered(array $arrayData): void
112
    {
113 16
        foreach ($arrayData['data'] as $value) {
114 16
            $strCommentParentKey = $this->setManageComment($arrayData['commentParentKey'], $value);
115 16
            $this->setElementsOrdered([
116 16
                'commentParentKey' => $strCommentParentKey,
117 16
                'data'             => $value,
118 16
                'tag'              => $arrayData['tag'],
119 16
            ]);
120
        }
121
    }
122
123 16
    private function setPrepareXml(string $strFile, array $arrayDocumentData, int $intIdent = 4): void
124
    {
125 16
        $this->objXmlWriter = new \XMLWriter();
126 16
        $this->objXmlWriter->openURI($strFile);
127 16
        $this->objXmlWriter->setIndent(true);
128 16
        $this->objXmlWriter->setIndentString(str_repeat(' ', $intIdent));
129 16
        $this->objXmlWriter->startDocument('1.0', 'UTF-8');
130 16
        $this->objXmlWriter->startElement($arrayDocumentData['DocumentTagName']);
131 16
        foreach ($arrayDocumentData['DocumentNameSpaces'] as $key => $value) {
132 16
            if ($key === '') {
133 16
                $strValue = sprintf($value, $arrayDocumentData['DocumentTagName']);
134 16
                $this->objXmlWriter->writeAttributeNS(null, 'xmlns', null, $strValue);
135
            } else {
136 16
                $this->objXmlWriter->writeAttributeNS('xmlns', $key, null, $value);
137
            }
138
        }
139 16
        if (array_key_exists('SchemaLocation', $arrayDocumentData)) {
140 11
            $this->objXmlWriter->writeAttribute('xsi:schemaLocation', $arrayDocumentData['SchemaLocation']);
141
        }
142
    }
143
144 16
    private function setProduceMiddleXml(array $arrayData): void
145
    {
146 16
        foreach ($this->arrayProcessing['OptionalElementsHeader'] as $key => $strLogicType) {
147 16
            if (array_key_exists($key, $arrayData)) {
148
                switch($strLogicType) {
149 16
                    case 'SingleCompany':
150 16
                        $this->setElementsOrdered([
151 16
                            'commentParentKey' => $key,
152 16
                            'data'             => $arrayData[$key]['Party'],
153 16
                            'tag'              => $key,
154 16
                        ]);
155 16
                        break;
156
                    default:
157 16
                        $arrayInput = [
158 16
                            'commentParentKey' => $key,
159 16
                            'data'             => $arrayData,
160 16
                            'tag'              => $key
161 16
                        ];
162 16
                        $this->setDecisionElements($arrayInput, $key, $key, $strLogicType);
163 16
                        break;
164
                }
165
            }
166
        }
167
    }
168
169 16
    private function setSingleComment(array $arrayInput): void
170
    {
171 16
        if (array_key_exists('commentParentKey', $arrayInput)) {
172 16
            $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $arrayInput['tag']]));
173 16
            if (str_ends_with($arrayInput['tag'], 'Quantity')) {
174 16
                $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $arrayInput['tag']
175 16
                    . 'UnitOfMeasure']));
176
            }
177
        }
178
    }
179
180 16
    private function setSingleElementWithAttribute(array $arrayInput): void
181
    {
182 16
        $this->setSingleComment($arrayInput);
183 16
        if (is_array($arrayInput['data']) && array_key_exists('value', $arrayInput['data'])) {
184 16
            $this->objXmlWriter->startElement('cbc:' . $arrayInput['tag']);
185 16
            foreach ($arrayInput['data'] as $key => $value) {
186 16
                if ($key !== 'value') { // if is not value, must be an attribute
187 16
                    $this->objXmlWriter->writeAttribute($key, $value);
188
                }
189
            }
190 16
            $this->objXmlWriter->writeRaw($this->setNumericValue($arrayInput['tag'], $arrayInput['data']));
191 16
            $this->objXmlWriter->endElement();
192
        } else {
193 16
            $this->objXmlWriter->writeElement('cbc:' . $arrayInput['tag'], $arrayInput['data']);
194
        }
195
    }
196
197 16
    public function writeElectronicInvoice(string $strFile, array $inData, array $arrayFeatures): void
198
    {
199 16
        $this->getProcessingDetails();
200 16
        $arrayData = $this->loadSettingsAndManageDefaults($inData, $arrayFeatures);
201 16
        if (!array_key_exists('Ident', $arrayFeatures)) {
202 14
            $arrayFeatures['Ident'] = 4;
203
        }
204 16
        $this->setPrepareXml($strFile, $arrayData, $arrayFeatures['Ident']);
205 16
        $this->setHeaderCommonBasicComponents($arrayData['Header']['CommonBasicComponents-2']);
206 16
        $this->setProduceMiddleXml($arrayData['Header']['CommonAggregateComponents-2']);
207
        // multiple Lines
208 16
        $this->setMultipleElementsOrdered([
209 16
            'commentParentKey' => 'Lines',
210 16
            'data'             => $arrayData['Lines'],
211 16
            'tag'              => $arrayData['DocumentTagName'] . 'Line',
212 16
        ]);
213 16
        $this->objXmlWriter->endElement(); // Invoice or CreditNote
214 16
        $this->objXmlWriter->flush();
215
    }
216
}
217