PluginProbe
Moloni / 5.0.09
Moloni v5.0.09
5.0.10 5.0.09 5.0.08 5.0.07 5.0.06 trunk 0.4.0.00 0.4.8.1 3.0.10 3.0.11 3.0.35 3.0.36 3.0.37 3.0.38 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.0.46 3.0.47 3.0.48 3.0.49 3.0.50 All 98 releases
moloni / src / Controllers / OrderFees.php

OrderFees.php in Moloni 5.0.09, at src/Controllers/OrderFees.php

313 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Moloni\Controllers;
4
5 use Moloni\Curl;
6 use Moloni\Exceptions\APIException;
7 use Moloni\Exceptions\GenericException;
8 use Moloni\Tools;
9 use WC_Order_Item_Fee;
10
11 class OrderFees
12 {
13
14 /** @var int */
15 public $product_id = 0;
16
17 /** @var int */
18 private $index;
19
20 /** @var array */
21 private $taxes = [];
22
23 /** @var float */
24 private $qty;
25
26 /** @var float */
27 private $price;
28
29 /** @var string */
30 private $exemption_reason;
31
32 /** @var string */
33 private $name;
34
35 /** @var float */
36 private $discount;
37
38 /** @var WC_Order_Item_Fee */
39 private $fee;
40
41 /** @var string */
42 private $reference;
43
44 /** @var int */
45 private $category_id;
46
47 private $type = 2;
48 private $summary = '';
49 private $ean = '';
50 private $unit_id;
51 private $has_stock = 0;
52 private $stock = 0;
53 private $at_product_category = 'M';
54
55 /** @var bool */
56 private $hasIVA = false;
57
58 /** @var array */
59 private $fiscalData;
60
61 /**
62 * OrderProduct constructor.
63 * @param WC_Order_Item_Fee $fee
64 * @param int $index
65 */
66 public function __construct($fee, $index = 0, $fiscalData = [])
67 {
68 $this->fee = $fee;
69 $this->index = $index;
70 $this->fiscalData = $fiscalData;
71 }
72
73 /**
74 * @return $this
75 *
76 * @throws APIException
77 * @throws GenericException
78 */
79 public function create()
80 {
81 $this->qty = 1;
82 $this->price = (float)$this->fee['line_total'];
83
84 $feeName = $this->fee->get_name();
85 $this->name = !empty($feeName) ? $feeName : 'Taxa';
86
87 $this
88 ->setReference()
89 ->setDiscount()
90 ->setTaxes()
91 ->setProductId();
92
93 return $this;
94 }
95
96 /**
97 * @return $this
98 */
99 private function setReference()
100 {
101 $this->reference = 'Fee';
102 return $this;
103 }
104
105 /**
106 * @return $this
107 *
108 * @throws APIException
109 * @throws GenericException
110 */
111 private function setProductId()
112 {
113 $searchProduct = Curl::simple('products/getByReference', ['reference' => $this->reference, 'with_invisible' => true, 'exact' => 1]);
114
115 if (!empty($searchProduct) && isset($searchProduct[0]['product_id'])) {
116 if ($searchProduct[0]['visibility_id'] === 1) {
117 $this->product_id = $searchProduct[0]['product_id'];
118 } else {
119 throw new GenericException('Produto com referência ' . $this->reference . ' tem de estar ativo.');
120 }
121
122 return $this;
123 }
124
125 // Lets create the shipping product
126 $this
127 ->setCategory()
128 ->setUnitId();
129
130 $insert = Curl::simple('products/insert', $this->mapPropsToValues(true));
131 if (isset($insert['product_id'])) {
132 $this->product_id = $insert['product_id'];
133 return $this;
134 }
135
136 throw new GenericException(__('Erro ao inserir Taxa da encomenda'));
137 }
138
139 /**
140 * @return OrderFees
141 *
142 * @throws APIException
143 * @throws GenericException
144 */
145 private function setCategory()
146 {
147 $categoryName = 'Loja Online';
148
149 $categoryObj = new ProductCategory($categoryName);
150
151 if (!$categoryObj->loadByName()) {
152 $categoryObj->create();
153 }
154
155 $this->category_id = $categoryObj->category_id;
156
157 return $this;
158 }
159
160 /**
161 * @return $this
162 *
163 * @throws GenericException
164 */
165 private function setUnitId()
166 {
167 if (defined('MEASURE_UNIT')) {
168 $this->unit_id = MEASURE_UNIT;
169 } else {
170 throw new GenericException(__('Unidade de medida não definida!'));
171 }
172
173 return $this;
174 }
175
176
177 /**
178 * Set the discount in percentage
179 * @return $this
180 */
181 private function setDiscount()
182 {
183 $this->discount = $this->price <= 0 ? 100 : 0;
184
185 if ($this->discount < 0) {
186 $this->discount = 0;
187 } elseif ($this->discount > 100) {
188 $this->discount = 100;
189 }
190
191 return $this;
192 }
193
194 /**
195 * Set the taxes of a product
196 *
197 * @return OrderFees
198 *
199 * @throws APIException
200 */
201 private function setTaxes()
202 {
203 $taxedArray = $this->fee->get_taxes();
204 $taxedValue = 0.0;
205 $taxRate = 0;
206
207 if (isset($taxedArray['total']) && count($taxedArray['total']) > 0) {
208 foreach ($taxedArray['total'] as $value) {
209 $taxedValue += (float)$value;
210 }
211
212 $taxRate = round(($taxedValue * 100) / $this->price);
213 }
214
215 if ((float)$taxRate > 0) {
216 $this->taxes[] = $this->setTax($taxRate);
217 }
218
219 if (!$this->hasIVA) {
220 $exemptionReason = '';
221
222 if ($this->isCountryIntraCommunity()) {
223 $exemptionReason = defined('EXEMPTION_REASON_SHIPPING') ? EXEMPTION_REASON_SHIPPING : '';
224 } else {
225 if (defined('EXEMPTION_REASON_SHIPPING_EXTRA_COMMUNITY')) {
226 $exemptionReason = EXEMPTION_REASON_SHIPPING_EXTRA_COMMUNITY;
227 } elseif (defined('EXEMPTION_REASON_SHIPPING')) {
228 $exemptionReason = EXEMPTION_REASON_SHIPPING;
229 }
230 }
231
232 $this->exemption_reason = $exemptionReason;
233 }
234
235 return $this;
236 }
237
238 /**
239 * @param float $taxRate Tax Rate in percentage
240 *
241 * @return array
242 *
243 * @throws APIException
244 */
245 private function setTax($taxRate)
246 {
247 $moloniTax = Tools::getTaxFromRate((float)$taxRate, $this->fiscalData['code']);
248
249 $tax = [];
250 $tax['tax_id'] = $moloniTax['tax_id'];
251 $tax['value'] = $taxRate;
252 $tax['order'] = is_array($this->taxes) ? count($this->taxes) : 0;
253 $tax['cumulative'] = 0;
254
255 if ((int) $moloniTax['saft_type'] === 1) {
256 $this->hasIVA = true;
257 }
258
259 return $tax;
260 }
261
262 /**
263 * @param bool $toInsert
264 * @return array
265 */
266 public function mapPropsToValues($toInsert = false)
267 {
268 $values = [];
269
270 $values['product_id'] = $this->product_id;
271 $values['name'] = $this->name;
272 $values['summary'] = '';
273 $values['qty'] = $this->qty;
274 $values['price'] = $this->price;
275 $values['discount'] = $this->discount;
276 $values['order'] = $this->index;
277 $values['exemption_reason'] = $this->exemption_reason;
278 $values['taxes'] = $this->taxes;
279
280 if ($toInsert) {
281 $values['reference'] = $this->reference;
282 $values['type'] = $this->type;
283 $values['stock'] = $this->stock;
284 $values['has_stock'] = $this->has_stock;
285 $values['at_product_category'] = $this->at_product_category;
286 $values['summary'] = $this->summary;
287 $values['ean'] = $this->ean;
288 $values['unit_id'] = $this->unit_id;
289 $values['category_id'] = $this->category_id;
290 }
291
292 return $values;
293 }
294
295 /**
296 * Check if country is intra community
297 *
298 * @return bool
299 */
300 private function isCountryIntraCommunity(): bool
301 {
302 if (!isset(Tools::$europeanCountryCodes[$this->fiscalData['code']])) {
303 return false;
304 }
305
306 if ($this->fiscalData['code'] === 'ES' && in_array($this->fiscalData['state'], ['TF', 'GC'])) {
307 return false;
308 }
309
310 return true;
311 }
312 }
313