Skip to content

Commit bb2dff4

Browse files
committed
Merge branch 'WP-160' into 'main'
fix: calculate tax for order items See merge request ecommerce_modules/cms/wordpress/wordpress!70
2 parents 546fcf9 + 34b302b commit bb2dff4

2 files changed

Lines changed: 123 additions & 50 deletions

File tree

src/Actions/OrderCreateAction.php

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Cdek\Model\Service;
2929
use Cdek\Model\ShippingItem;
3030
use Cdek\Model\Tariff;
31+
use Cdek\Model\Tax;
3132
use Cdek\Model\ValidationResult;
3233
use Cdek\Note;
3334
use Cdek\Traits\CanBeCreated;
@@ -288,58 +289,32 @@ private function buildPackagesData(?array $packages = null): array
288289
$shouldConvert = $this->order->currency !== 'RUB' &&
289290
function_exists('wcml_get_woocommerce_currency_option') ? $this->order->currency : null;
290291

291-
return array_map(function (array $p) use (&$shouldConvert, &$orderItems, &$shouldPay) {
292+
return array_map(function (array $p) use ($shouldConvert, $orderItems, $shouldPay) {
292293
$weight = 0;
293294

294-
$items = array_values(array_filter(array_map(function ($item) use (
295-
&$shouldConvert,
296-
&$shouldPay,
297-
&$orderItems,
298-
&$weight
299-
) {
300-
if ($item instanceof WC_Order_Item_Product) {
301-
$qty = (int)$item->get_quantity();
302-
} else {
303-
$qty = (int)$item['qty'];
304-
$item = $orderItems[$item['id']] ?? null;
305-
}
306-
307-
if ($item === null) {
308-
return null;
309-
}
310-
311-
assert($item instanceof WC_Order_Item_Product);
312-
$product = $item->get_product();
313-
314-
$w = WeightConverter::getWeightInGrams($product->get_weight());
315-
$weight += $qty * $w;
316-
$cost = $shouldConvert === null ? (float)$item->get_total() : $this->convertCurrencyToRub(
317-
(float)$item->get_total(),
318-
$shouldConvert,
319-
);
320-
321-
$cost /= $qty;
322-
323-
if ($shouldPay !== null) {
324-
if ($shouldPay !== 0) {
325-
$paymentValue = (int)(($shouldPay / 100) * $cost);
326-
} else {
327-
$paymentValue = $cost;
328-
}
329-
} else {
330-
$paymentValue = 0;
331-
}
332-
333-
return [
334-
'ware_key' => $product->get_sku() ?: $product->get_id(),
335-
'payment' => ['value' => $paymentValue],
336-
'name' => $item->get_name(),
337-
'cost' => $cost,
338-
'amount' => $qty,
339-
'weight' => $w,
340-
'weight_gross' => $w + 1,
341-
];
342-
}, $p['items'] ?: $orderItems)));
295+
$items = array_values(
296+
array_filter(
297+
array_map(
298+
static function($item) use ($shouldConvert, $shouldPay, $orderItems, &$weight){
299+
if ($item instanceof WC_Order_Item_Product) {
300+
$qty = (int)$item->get_quantity();
301+
} else {
302+
$qty = (int)$item['qty'];
303+
$item = $orderItems[$item['id']] ?? null;
304+
}
305+
306+
if ($item === null) {
307+
return null;
308+
}
309+
310+
assert($item instanceof WC_Order_Item_Product);
311+
312+
return $this->buildItemData($item, $qty, $shouldConvert, $shouldPay, $weight);
313+
},
314+
$p['items'] ?: $orderItems
315+
)
316+
)
317+
);
343318

344319
$package = [
345320
'number' => sprintf('%s_%s', $this->order->id, StringHelper::generateRandom(5)),
@@ -358,6 +333,61 @@ function_exists('wcml_get_woocommerce_currency_option') ? $this->order->currency
358333
}, $packages);
359334
}
360335

336+
private function buildItemData(
337+
WC_Order_Item_Product $item,
338+
int $qty,
339+
?string $shouldConvert,
340+
?int $shouldPay,
341+
int &$weight
342+
): array
343+
{
344+
$product = $item->get_product();
345+
346+
$w = WeightConverter::getWeightInGrams($product->get_weight());
347+
$weight += $qty * $w;
348+
$cost = $shouldConvert === null ? (float)wc_get_price_including_tax($product) :
349+
$this->convertCurrencyToRub(
350+
(float)wc_get_price_including_tax($product),
351+
$shouldConvert,
352+
);
353+
354+
$payment = ['value' => 0];
355+
356+
if ($shouldPay !== null) {
357+
if ($shouldPay !== 0) {
358+
$payment['value'] = (int)(($shouldPay / 100) * $cost);
359+
360+
if($product->is_taxable()){
361+
$taxCost = $shouldConvert === null ? (float)$item->get_total_tax() :
362+
$this->convertCurrencyToRub(
363+
(float)$item->get_total_tax(),
364+
$shouldConvert,
365+
);
366+
367+
if($taxCost > 0){
368+
$payment['vat_sum'] = (int)(($shouldPay / 100) * $taxCost);
369+
$payment['vat_rate'] = Tax::getTax($product->get_tax_class());
370+
}else{
371+
$payment['vat_sum'] = 0;
372+
$payment['vat_rate'] = 0;
373+
}
374+
}
375+
} else {
376+
$payment['value'] = $cost;
377+
}
378+
}
379+
380+
return [
381+
'ware_key' => $product->get_sku() ?: $product->get_id(),
382+
'payment' => $payment,
383+
'name' => $item->get_name(),
384+
'cost' => $cost,
385+
'amount' => $qty,
386+
'weight' => $w,
387+
'weight_gross' => $w + 1,
388+
];
389+
}
390+
361391
private function convertCurrencyToRub(float $cost, string $currency): float
362392
{
363393
global $woocommerce_wpml;

src/Model/Tax.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace {
6+
defined('ABSPATH') or exit;
7+
}
8+
9+
namespace Cdek\Model {
10+
use WC_Tax;
11+
12+
class Tax
13+
{
14+
private const AVAILABLE_TAX = [
15+
null, 0, 5, 10, 12, 20
16+
];
17+
18+
public static function getTax(string $rateClass): ?int
19+
{
20+
$taxRates = WC_Tax::get_rates_for_tax_class($rateClass);
21+
22+
if(!is_array($taxRates)){
23+
return self::AVAILABLE_TAX[0];
24+
}
25+
26+
if(count($taxRates) === 0){
27+
return self::AVAILABLE_TAX[0];
28+
}
29+
30+
$taxValue = (int)round(
31+
array_sum(
32+
array_map(static fn($tax) => $tax->tax_rate, $taxRates),
33+
),
34+
);
35+
36+
if(in_array($taxValue, self::AVAILABLE_TAX, true)){
37+
return $taxValue;
38+
}
39+
40+
return self::AVAILABLE_TAX[0];
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)