Passed
Push — main ( 81eb9b...13de75 )
by Daniel
02:11
created

ElectornicInvoiceWrite::setElementWithAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2024 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\efactura;
30
31
class ElectornicInvoiceWrite
32
{
33
34
    use TraitVersions;
0 ignored issues
show
introduced by
The trait danielgp\efactura\TraitVersions requires some properties which are not provided by danielgp\efactura\ElectornicInvoiceWrite: $currencyID, $unitCode
Loading history...
35
36
    protected $objXmlWriter;
37
38
    private function setCompanyElementsOrdered(array $arrayInput): void {
39
        $this->setElementComment($arrayInput['commentParentKey']);
40
        $this->objXmlWriter->startElement('cac:' . $arrayInput['tag']);
41
        $arrayCustomOrder = $this->arraySettings['CustomOrder'][$arrayInput['commentParentKey']];
42
        foreach ($arrayCustomOrder as $value) {
43
            if (array_key_exists($value, $arrayInput['data'])) {
44
                $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $value]));
45
                if (in_array($value, ['CreditNoteQuantity', 'InvoicedQuantity'])) {
46
                    $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $value
47
                        . 'UnitOfMeasure']));
48
                }
49
                if (substr($value, -6) === 'Amount') {
50
                    $this->objXmlWriter->startElement('cbc:' . $value);
51
                    $this->objXmlWriter->writeAttribute('currencyID', $arrayInput['data'][$value]['currencyID']);
52
                    $this->objXmlWriter->writeRaw($arrayInput['data'][$value]['value']);
53
                    $this->objXmlWriter->endElement();
54
                } elseif (substr($value, -8) === 'Quantity') {
55
                    $this->objXmlWriter->startElement('cbc:' . $value);
56
                    $this->objXmlWriter->writeAttribute('unitCode', $arrayInput['data'][$value]['unitCode']);
57
                    $this->objXmlWriter->writeRaw($arrayInput['data'][$value]['value']);
58
                    $this->objXmlWriter->endElement();
59
                } elseif (is_array($arrayInput['data'][$value])) {
60
                    $this->objXmlWriter->startElement('cac:' . $value);
61
                    foreach ($arrayInput['data'][$value] as $key2 => $value2) {
62
                        $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $value, $key2]));
63
                        $this->objXmlWriter->writeElement('cbc:' . $key2, $value2);
64
                    }
65
                    $this->objXmlWriter->endElement();
66
                } else {
67
                    $this->objXmlWriter->writeElement('cbc:' . $value, $arrayInput['data'][$value]);
68
                }
69
            }
70
        }
71
        $this->objXmlWriter->endElement(); // $key
72
    }
73
74
    private function setDocumentTag(array $arrayDocumentData): void {
75
        $this->objXmlWriter->startElement($arrayDocumentData['DocumentTagName']);
76
        foreach ($arrayDocumentData['DocumentNameSpaces'] as $key => $value) {
77
            if ($key === '') {
78
                $strValue = sprintf($value, $arrayDocumentData['DocumentTagName']);
79
                $this->objXmlWriter->writeAttributeNS(NULL, 'xmlns', NULL, $strValue);
80
            } else {
81
                $this->objXmlWriter->writeAttributeNS('xmlns', $key, NULL, $value);
82
            }
83
        }
84
        if (array_key_exists('SchemaLocation', $arrayDocumentData)) {
85
            $this->objXmlWriter->writeAttribute('xsi:schemaLocation', $arrayDocumentData['SchemaLocation']);
86
        }
87
    }
88
89
    private function setElementWithAttribute(array $arrayInput): void {
90
        $this->setElementComment(implode('_', [$arrayInput['commentParentKey'], $arrayInput['tag']]));
91
        $this->objXmlWriter->startElement('cbc:' . $arrayInput['tag']);
92
        $this->objXmlWriter->writeAttribute($arrayInput['attrib'], $arrayInput['data'][$arrayInput['attrib']]);
93
        $this->objXmlWriter->writeRaw($arrayInput['data']['value']);
94
        $this->objXmlWriter->endElement();
95
    }
96
97
    private function setHeaderCommonAggregateComponentsCompanies(array $arrayParameters): void {
98
        $key              = $arrayParameters['tag'];
99
        $this->setElementComment($key);
100
        $this->objXmlWriter->startElement('cac:' . $key);
101
        $this->objXmlWriter->startElement('cac:Party');
102
        $arrayCustomOrder = $this->arraySettings['CustomOrder'][$key];
103
        foreach ($arrayCustomOrder as $value) {
104
            if (array_key_exists($value, $arrayParameters['data'])) {
105
                $this->setCompanyElementsOrdered([
106
                    'commentParentKey' => implode('_', [$key, $value]),
107
                    'data'             => $arrayParameters['data'][$value],
108
                    'tag'              => $value,
109
                ]);
110
            }
111
        }
112
        $this->objXmlWriter->endElement(); // Party
113
        $this->objXmlWriter->endElement(); // $key
114
    }
115
116
    private function setHeaderCommonAggregateComponentsTaxTotal(array $arrayParameters): void {
117
        $key = $arrayParameters['tag'];
118
        $this->setElementComment($key);
119
        $this->objXmlWriter->startElement('cac:' . $key);
120
        $this->setElementWithAttribute([
121
            'attrib'           => 'currencyID',
122
            'commentParentKey' => $key,
123
            'data'             => $arrayParameters['data']['TaxAmount'],
124
            'tag'              => 'TaxAmount',
125
        ]);
126
        foreach ($arrayParameters['data']['TaxSubtotal'] as $value) {
127
            $this->objXmlWriter->startElement('cac:TaxSubtotal');
128
            $this->setElementWithAttribute([
129
                'attrib'           => 'currencyID',
130
                'commentParentKey' => implode('_', [$key, 'TaxSubtotal']),
131
                'data'             => $value['TaxableAmount'],
132
                'tag'              => 'TaxableAmount',
133
            ]);
134
            $this->setElementWithAttribute([
135
                'attrib'           => 'currencyID',
136
                'commentParentKey' => implode('_', [$key, 'TaxSubtotal']),
137
                'data'             => $value['TaxAmount'],
138
                'tag'              => 'TaxAmount',
139
            ]);
140
            $this->setTaxCategory([
141
                'commentParentKey' => implode('_', [$key, 'TaxSubtotal', 'TaxCategory']),
142
                'data'             => $value['TaxCategory'],
143
                'tag'              => 'TaxCategory',
144
            ]);
145
            $this->objXmlWriter->endElement(); // TaxSubtotal
146
        }
147
        $this->objXmlWriter->endElement(); // $key
148
    }
149
150
    private function setHeaderCommonBasicComponents(array $arrayElementWithData): void {
151
        $arrayCustomOrdered = $this->arraySettings['CustomOrder']['Header_CBC'];
152
        foreach ($arrayCustomOrdered as $value) {
153
            $this->setElementComment($value);
154
            $this->objXmlWriter->writeElement('cbc:' . $value, $arrayElementWithData[$value]);
155
        }
156
    }
157
158
    private function setTaxCategory(array $arrayParameters): void {
159
        $key = $arrayParameters['tag'];
160
        $this->objXmlWriter->startElement('cac:' . $key);
161
        $this->setElementComment(implode('_', [$arrayParameters['commentParentKey'], 'ID']));
162
        $this->objXmlWriter->writeElement('cbc:ID', $arrayParameters['data']['ID']);
163
        $this->setElementComment(implode('_', [$arrayParameters['commentParentKey'], 'Percent']));
164
        $this->objXmlWriter->writeElement('cbc:Percent', $arrayParameters['data']['Percent']);
165
        $this->objXmlWriter->startElement('cac:TaxScheme');
166
        $this->objXmlWriter->writeElement('cbc:ID', $arrayParameters['data']['TaxScheme']['ID']);
167
        $this->objXmlWriter->endElement(); // $key
168
        $this->objXmlWriter->endElement(); // $key
169
    }
170
171
    public function writeElectronicInvoice(string $strFile, array $arrayData, bool $bolComments): void {
172
        $this->objXmlWriter = new \XMLWriter();
173
        $this->objXmlWriter->openURI($strFile);
174
        $this->objXmlWriter->setIndent(true);
175
        $this->objXmlWriter->setIndentString(str_repeat(' ', 4));
176
        $this->objXmlWriter->startDocument('1.0', 'UTF-8');
177
        // if no DocumentNameSpaces seen take Default ones from local configuration
178
        $this->getSettingsFromFileIntoMemory($bolComments);
179
        $arrayDefaults      = $this->getDefaultsIntoDataSet($arrayData);
180
        if ($arrayDefaults !== []) {
181
            $arrayData = array_merge($arrayData, $arrayDefaults['Root']);
182
            if (!array_key_exists('CustomizationID', $arrayData['Header']['CommonBasicComponents-2'])) {
183
                $arrayData['Header']['CommonBasicComponents-2']['CustomizationID'] = $arrayDefaults['CIUS-RO'];
184
                $arrayData['Header']['CommonBasicComponents-2']['UBLVersionID']    = $arrayDefaults['UBL'];
185
            }
186
        }
187
        $this->setDocumentTag($arrayData);
188
        $this->setHeaderCommonBasicComponents($arrayData['Header']['CommonBasicComponents-2'],);
189
        $arrayAggegateComponents = $arrayData['Header']['CommonAggregateComponents-2'];
190
        foreach (['AccountingSupplierParty', 'AccountingCustomerParty'] as $strCompanyType) {
191
            $this->setHeaderCommonAggregateComponentsCompanies([
192
                'data'   => $arrayAggegateComponents[$strCompanyType]['Party'],
193
                'tag'    => $strCompanyType,
194
                'subTag' => 'Party',
195
            ]);
196
        }
197
        // multiple accounts can be specified within PaymentMeans
198
        if ($arrayData['DocumentTagName'] === 'Invoice') {
199
            foreach ($arrayAggegateComponents['PaymentMeans'] as $value) {
200
                $this->setCompanyElementsOrdered([
201
                    'commentParentKey' => 'PaymentMeans',
202
                    'data'             => $value,
203
                    'tag'              => 'PaymentMeans',
204
                ]);
205
            }
206
        }
207
        $this->setHeaderCommonAggregateComponentsTaxTotal([
208
            'data' => $arrayAggegateComponents['TaxTotal'],
209
            'tag'  => 'TaxTotal',
210
        ]);
211
        $this->setCompanyElementsOrdered([
212
            'commentParentKey' => 'LegalMonetaryTotal',
213
            'data'             => $arrayAggegateComponents['LegalMonetaryTotal'],
214
            'tag'              => 'LegalMonetaryTotal',
215
        ]);
216
        // multiple Lines
217
        foreach ($arrayData['Lines'] as $value) {
218
            $this->setCompanyElementsOrdered([
219
                'commentParentKey' => 'Lines',
220
                'data'             => $value,
221
                'tag'              => $arrayData['DocumentTagName'] . 'Line',
222
            ]);
223
        }
224
        $this->objXmlWriter->endElement(); // Invoice or CreditNote
225
        $this->objXmlWriter->flush();
226
    }
227
}
228