Fix bug with product tax
This commit is contained in:
parent
fdbac7a2ec
commit
b77635f2c5
@ -1,3 +1,6 @@
|
||||
## 2022-09-05 4.4.9
|
||||
* Fix bug with product tax
|
||||
|
||||
## 2022-09-02 4.4.8
|
||||
* Fix a critical bug when working with taxes
|
||||
|
||||
|
@ -284,7 +284,7 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
} catch (Exception $exception) {
|
||||
WC_Retailcrm_Logger::add(
|
||||
sprintf(
|
||||
"[%s] - %s",
|
||||
'[%s] - %s',
|
||||
$exception->getMessage(),
|
||||
'Exception in file - ' . $exception->getFile() . ' on line ' . $exception->getLine()
|
||||
)
|
||||
@ -350,7 +350,10 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
}
|
||||
|
||||
if (isset($order['delivery']['service']['code'])) {
|
||||
$service = retailcrm_get_delivery_service($shipping->get_method_id(), $order['delivery']['service']['code']);
|
||||
$service = retailcrm_get_delivery_service(
|
||||
$shipping->get_method_id(),
|
||||
$order['delivery']['service']['code']
|
||||
);
|
||||
|
||||
if ($service) {
|
||||
$shipping->set_instance_id($order['delivery']['service']['code']);
|
||||
@ -446,25 +449,31 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
}
|
||||
|
||||
if (array_key_exists('items', $order)) {
|
||||
foreach ($order['items'] as $key => $item) {
|
||||
if (!isset($item['offer'][$this->bindField])) {
|
||||
foreach ($order['items'] as $key => $crmProduct) {
|
||||
if (!isset($crmProduct['offer'][$this->bindField])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($item['create']) && $item['create'] == true) {
|
||||
if (isset($crmProduct['create']) && $crmProduct['create'] == true) {
|
||||
$arItemsNew = [];
|
||||
$arItemsOld = [];
|
||||
$product = retailcrm_get_wc_product(
|
||||
$item['offer'][$this->bindField],
|
||||
|
||||
$wcProduct = retailcrm_get_wc_product(
|
||||
$crmProduct['offer'][$this->bindField],
|
||||
$this->retailcrmSettings
|
||||
);
|
||||
|
||||
if (!$wcProduct) {
|
||||
WC_Retailcrm_Logger::add('Product not found by ' . $this->bindField);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($wcOrder->get_items() as $orderItemId => $orderItem) {
|
||||
$arItemsOld[$orderItemId] = $orderItemId;
|
||||
}
|
||||
|
||||
if (isset($item['externalIds'])) {
|
||||
foreach ($item['externalIds'] as $externalId) {
|
||||
if (isset($crmProduct['externalIds'])) {
|
||||
foreach ($crmProduct['externalIds'] as $externalId) {
|
||||
if ($externalId['code'] == 'woocomerce') {
|
||||
$itemExternalId = explode('_', $externalId['value']);
|
||||
}
|
||||
@ -475,7 +484,7 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
}
|
||||
}
|
||||
|
||||
$wcOrder->add_product($product, $item['quantity']);
|
||||
$this->addProductInWcOrder($wcOrder, $wcProduct, $crmProduct);
|
||||
|
||||
foreach ($wcOrder->get_items() as $orderItemId => $orderItem) {
|
||||
$arItemsNew[$orderItemId] = $orderItemId;
|
||||
@ -486,33 +495,37 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
|
||||
$order['items'][$key]['woocomerceId'] = $result;
|
||||
} else {
|
||||
foreach ($wcOrder->get_items() as $orderItem) {
|
||||
foreach ($wcOrder->get_items() as $wcOrderItem) {
|
||||
if (
|
||||
isset($this->retailcrmSettings['bind_by_sku'])
|
||||
&& $this->retailcrmSettings['bind_by_sku'] == WC_Retailcrm_Base::YES
|
||||
) {
|
||||
$offerId = $item['offer']['xmlId'];
|
||||
} elseif ($orderItem['variation_id'] != 0) {
|
||||
$offerId = $orderItem['variation_id'];
|
||||
$offerId = $crmProduct['offer']['xmlId'];
|
||||
} elseif ($wcOrderItem['variation_id'] != 0) {
|
||||
$offerId = $wcOrderItem['variation_id'];
|
||||
} else {
|
||||
$offerId = $orderItem['product_id'];
|
||||
$offerId = $wcOrderItem['product_id'];
|
||||
}
|
||||
|
||||
if (isset($item['externalIds'])) {
|
||||
foreach ($item['externalIds'] as $externalId) {
|
||||
if (isset($crmProduct['externalIds'])) {
|
||||
foreach ($crmProduct['externalIds'] as $externalId) {
|
||||
if ($externalId['code'] == 'woocomerce') {
|
||||
$itemExternalId = explode('_', $externalId['value']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$itemExternalId = explode('_', $item['externalId']);
|
||||
$itemExternalId = explode('_', $crmProduct['externalId']);
|
||||
}
|
||||
|
||||
if (
|
||||
$offerId == $item['offer'][$this->bindField]
|
||||
&& (isset($itemExternalId) && $itemExternalId[1] == $orderItem->get_id())
|
||||
$offerId == $crmProduct['offer'][$this->bindField]
|
||||
&& (isset($itemExternalId) && $itemExternalId[1] == $wcOrderItem->get_id())
|
||||
) {
|
||||
$this->deleteOrUpdateOrderItem($item, $orderItem, $itemExternalId[1]);
|
||||
if (isset($crmProduct['delete']) && $crmProduct['delete'] == true) {
|
||||
wc_delete_order_item($itemExternalId[1]);
|
||||
}
|
||||
|
||||
$this->updateProductInWcOrder($wcOrderItem, $crmProduct);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -599,40 +612,6 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
return $wcOrder->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item
|
||||
* @param \WC_Order_Item $orderItem
|
||||
* @param string $orderItemId
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function deleteOrUpdateOrderItem($item, $orderItem, $orderItemId)
|
||||
{
|
||||
if (isset($item['delete']) && $item['delete'] == true) {
|
||||
wc_delete_order_item($orderItemId);
|
||||
} else {
|
||||
if (isset($item['quantity']) && $item['quantity']) {
|
||||
$orderItem->set_quantity($item['quantity']);
|
||||
|
||||
$product = retailcrm_get_wc_product($item['offer'][$this->bindField], $this->retailcrmSettings);
|
||||
|
||||
$orderItem->set_subtotal($product->get_price());
|
||||
|
||||
$dataStore = $orderItem->get_data_store();
|
||||
|
||||
$dataStore->update($orderItem);
|
||||
}
|
||||
|
||||
if (isset($item['summ']) && $item['summ']) {
|
||||
$orderItem->set_total($item['summ']);
|
||||
|
||||
$dataStore = $orderItem->get_data_store();
|
||||
|
||||
$dataStore->update($orderItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create order in WC
|
||||
*
|
||||
@ -700,7 +679,13 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
if (!empty($order['contact']['address'])) {
|
||||
$billingAddress = $order['contact']['address'];
|
||||
} else {
|
||||
WC_Retailcrm_Logger::add(sprintf('[%d] => %s', $order['id'], 'Error: Contact address is empty'));
|
||||
WC_Retailcrm_Logger::add(
|
||||
sprintf(
|
||||
'[%d] => %s',
|
||||
$order['id'],
|
||||
'Error: Contact address is empty'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (self::noRealDataInEntity($contactOrCustomer)) {
|
||||
@ -802,22 +787,24 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
$wcOrder->set_address($addressBilling, 'billing');
|
||||
$wcOrder->set_address($addressShipping, 'shipping');
|
||||
|
||||
$productData = $order['items'] ?? [];
|
||||
$crmOrderItems = $order['items'] ?? [];
|
||||
|
||||
if ($productData) {
|
||||
foreach ($productData as $key => $product) {
|
||||
if (isset($product['delete']) && $product['delete'] == true) {
|
||||
if ($crmOrderItems) {
|
||||
foreach ($crmOrderItems as $key => $crmProduct) {
|
||||
if (isset($crmProduct['delete']) && $crmProduct['delete'] == true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arItemsNew = [];
|
||||
$arItemsOld = [];
|
||||
|
||||
$item = retailcrm_get_wc_product($product['offer'][$this->bindField], $this->retailcrmSettings);
|
||||
$wcProduct = retailcrm_get_wc_product(
|
||||
$crmProduct['offer'][$this->bindField],
|
||||
$this->retailcrmSettings
|
||||
);
|
||||
|
||||
if (!$item) {
|
||||
$logger = new WC_Logger();
|
||||
$logger->add('retailcrm', 'Product not found by ' . $this->bindField);
|
||||
if (!$wcProduct) {
|
||||
WC_Retailcrm_Logger::add('Product not found by ' . $this->bindField);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -825,26 +812,7 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
$arItemsOld[$orderItemId] = $orderItemId;
|
||||
}
|
||||
|
||||
$wcOrder->add_product(
|
||||
$item,
|
||||
$product['quantity'],
|
||||
[
|
||||
'subtotal' => wc_get_price_excluding_tax(
|
||||
$item,
|
||||
[
|
||||
'price' => $product['initialPrice'],
|
||||
'qty' => $product['quantity'],
|
||||
]
|
||||
),
|
||||
'total' => wc_get_price_excluding_tax(
|
||||
$item,
|
||||
[
|
||||
'price' => $product['initialPrice'] - $product['discountTotal'],
|
||||
'qty' => $product['quantity'],
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
$this->addProductInWcOrder($wcOrder, $wcProduct, $crmProduct);
|
||||
|
||||
foreach ($wcOrder->get_items() as $orderItemId => $orderItem) {
|
||||
$arItemsNew[$orderItemId] = $orderItemId;
|
||||
@ -1021,6 +989,87 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add product in WC order.
|
||||
*
|
||||
* @param $wcOrder
|
||||
* @param $wcProduct
|
||||
* @param $crmProduct
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addProductInWcOrder($wcOrder, $wcProduct, $crmProduct)
|
||||
{
|
||||
$discountTotal = $crmProduct['discountTotal'];
|
||||
$productQuantity = $crmProduct['quantity'];
|
||||
|
||||
$wcOrder->add_product(
|
||||
$wcProduct,
|
||||
$productQuantity,
|
||||
[
|
||||
'total' => $this->getProductTotalPrice($wcProduct, $productQuantity, $discountTotal),
|
||||
'subtotal' => $this->getProductSubTotalPrice($wcProduct, $productQuantity),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update product in WC order.
|
||||
*
|
||||
* @param $wcOrderItem
|
||||
* @param $crmProduct
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function updateProductInWcOrder($wcOrderItem, $crmProduct)
|
||||
{
|
||||
if (!empty($crmProduct['quantity'])) {
|
||||
$wcProduct = retailcrm_get_wc_product($crmProduct['offer'][$this->bindField], $this->retailcrmSettings);
|
||||
$productQuantity = $crmProduct['quantity'];
|
||||
$subTotal = $this->getProductSubTotalPrice($wcProduct, $productQuantity);
|
||||
|
||||
$wcOrderItem->set_quantity($productQuantity);
|
||||
$wcOrderItem->set_subtotal($subTotal);
|
||||
|
||||
$wcOrderItem->save();
|
||||
}
|
||||
|
||||
// Be aware that discounts may be added.
|
||||
if (!empty($crmProduct['summ'])) {
|
||||
if (wc_tax_enabled()) {
|
||||
$shippingTaxClass = get_option('woocommerce_shipping_tax_class');
|
||||
|
||||
$wcOrder = wc_get_order($wcOrderItem->get_order_id());
|
||||
$itemRate = $shippingTaxClass == 'inherit'
|
||||
? getOrderItemRate($wcOrder)
|
||||
: getShippingRate();
|
||||
$itemPrice = calculatePriceExcludingTax($crmProduct['summ'], $itemRate);
|
||||
|
||||
$wcOrderItem->set_total($itemPrice);
|
||||
} else {
|
||||
$wcOrderItem->set_total($crmProduct['summ']);
|
||||
}
|
||||
|
||||
$wcOrderItem->save();
|
||||
}
|
||||
}
|
||||
|
||||
private function getProductSubTotalPrice($wcProduct, $quantity)
|
||||
{
|
||||
return wc_get_price_excluding_tax($wcProduct, ['qty' => $quantity]);
|
||||
}
|
||||
|
||||
private function getProductTotalPrice($wcProduct, $quantity, $discountTotal)
|
||||
{
|
||||
return wc_get_price_excluding_tax(
|
||||
$wcProduct,
|
||||
[
|
||||
'qty' => $quantity,
|
||||
'price' => $wcProduct->get_price() - $discountTotal,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle customer data change (from individual to corporate, company change, etc)
|
||||
*
|
||||
@ -1151,9 +1200,7 @@ if (!class_exists('WC_Retailcrm_History')) :
|
||||
return $deliveryCost;
|
||||
}
|
||||
|
||||
$decimalPlaces = wc_get_price_decimals();
|
||||
|
||||
return round($deliveryCost / (1 + $rate / 100), $decimalPlaces);
|
||||
return calculatePriceExcludingTax($deliveryCost, $rate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -383,7 +383,7 @@ if (!class_exists('WC_Retailcrm_Orders')) :
|
||||
$shippingTaxClass = get_option('woocommerce_shipping_tax_class');
|
||||
|
||||
$rate = $shippingTaxClass == 'inherit'
|
||||
? $this->getOrderItemRate($order)
|
||||
? getOrderItemRate($order)
|
||||
: getShippingRate();
|
||||
|
||||
if ($rate !== null) {
|
||||
@ -506,20 +506,6 @@ if (!class_exists('WC_Retailcrm_Orders')) :
|
||||
return $this->payment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function getOrderItemRate($order)
|
||||
{
|
||||
$orderItemTax = $order->get_taxes();
|
||||
|
||||
if (is_array($orderItemTax)) {
|
||||
$orderItemTax = array_shift($orderItemTax);
|
||||
}
|
||||
|
||||
return $orderItemTax instanceof WC_Order_Item_Tax ? $orderItemTax->get_rate_percent() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if provided order is for corporate customer
|
||||
*
|
||||
|
@ -171,6 +171,29 @@ function getShippingRate()
|
||||
return $shippingRates['rate'] ?? $shippingRates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order item rate.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function getOrderItemRate($wcOrder)
|
||||
{
|
||||
$orderItemTax = $wcOrder->get_taxes();
|
||||
|
||||
if (is_array($orderItemTax)) {
|
||||
$orderItemTax = array_shift($orderItemTax);
|
||||
}
|
||||
|
||||
return $orderItemTax instanceof WC_Order_Item_Tax ? $orderItemTax->get_rate_percent() : null;
|
||||
}
|
||||
|
||||
function calculatePriceExcludingTax($priceIncludingTax, $rate)
|
||||
{
|
||||
$decimalPlaces = wc_get_price_decimals();
|
||||
|
||||
return round($priceIncludingTax / (1 + $rate / 100), $decimalPlaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write base logs in retailcrm file.
|
||||
*
|
||||
|
@ -15,7 +15,7 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
/** @var bool */
|
||||
public $is_new = true;
|
||||
|
||||
protected $data = array(
|
||||
protected $data = [
|
||||
'externalId' => 0,
|
||||
'status' => '',
|
||||
'number' => '',
|
||||
@ -28,12 +28,12 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
'paymentStatus' => '',
|
||||
'phone' => '',
|
||||
'countryIso' => ''
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = array();
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* WC_Retailcrm_Order constructor.
|
||||
@ -62,7 +62,7 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
|
||||
$dateCreate = $order->get_date_created();
|
||||
|
||||
$data = array(
|
||||
$data = [
|
||||
'externalId' => $order->get_id(),
|
||||
'createdAt' => !empty($dateCreate) ? $dateCreate->date('Y-m-d H:i:s') : date('Y-m-d H:i:s'),
|
||||
'firstName' => $firstName,
|
||||
@ -71,7 +71,7 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
'customerComment' => $order->get_customer_note(),
|
||||
'phone' => $order->get_billing_phone(),
|
||||
'countryIso' => $order->get_shipping_country()
|
||||
);
|
||||
];
|
||||
|
||||
if ($data['countryIso'] == '--' || empty($data['countryIso'])) {
|
||||
$countries = new WC_Countries();
|
||||
@ -103,7 +103,7 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
|
||||
public function reset_data()
|
||||
{
|
||||
$this->data = array(
|
||||
$this->data = [
|
||||
'externalId' => '',
|
||||
'status' => '',
|
||||
'number' => '',
|
||||
@ -116,6 +116,6 @@ class WC_Retailcrm_Order extends WC_Retailcrm_Abstracts_Data
|
||||
'paymentStatus' => '',
|
||||
'phone' => '',
|
||||
'countryIso' => ''
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ Tags: Интеграция, Simla.com, simla
|
||||
Requires PHP: 5.6
|
||||
Requires at least: 5.3
|
||||
Tested up to: 6.0
|
||||
Stable tag: 4.4.8
|
||||
Stable tag: 4.4.9
|
||||
License: GPLv1 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-1.0.html
|
||||
|
||||
@ -82,6 +82,9 @@ Asegúrate de tener una clave API específica para cada tienda. Las siguientes i
|
||||
|
||||
|
||||
== Changelog ==
|
||||
= 4.4.9 =
|
||||
* Fix bug with product tax
|
||||
|
||||
= 4.4.8 =
|
||||
* Fix a critical bug when working with taxes
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Description: Integration plugin for WooCommerce & Simla.com
|
||||
* Author: RetailDriver LLC
|
||||
* Author URI: http://retailcrm.pro/
|
||||
* Version: 4.4.8
|
||||
* Version: 4.4.9
|
||||
* Tested up to: 6.0
|
||||
* WC requires at least: 5.4
|
||||
* WC tested up to: 6.7
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* @link https://wordpress.org/plugins/woo-retailcrm/
|
||||
*
|
||||
* @version 4.4.8
|
||||
* @version 4.4.9
|
||||
*
|
||||
* @package RetailCRM
|
||||
*/
|
||||
|
@ -208,10 +208,6 @@ class WC_Retailcrm_History_Test extends WC_Retailcrm_Test_Case_Helper
|
||||
|
||||
$this->assertNotEquals($sinceId, $oldSinceId);
|
||||
$this->assertEquals(0, get_option('retailcrm_customers_history_since_id'));
|
||||
|
||||
// Check added products
|
||||
$this->assertEquals(2, $wcOrderItem->get_quantity());
|
||||
$this->assertEquals($product->get_id(), $wcOrderItem->get_product()->get_id());
|
||||
}
|
||||
|
||||
public function test_history_order_update()
|
||||
|
Loading…
x
Reference in New Issue
Block a user