diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..10d458ee --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +## 2018-02-19 v.2.0.6 +* Исправлено возникновение Warning на PHP 7.2 при генерации каталога товаров +* Добавлена настройка выгрузки заказов из RetailCRM с определенными способами оформления +* Выгрузка изменений из RetailCRM осуществляется по sinceId + +## 2018-02-02 v.2.0.5 +* Исправлен неверный подсчет скидки на товары \ No newline at end of file diff --git a/woo-retailcrm/include/class-wc-retailcrm-base.php b/woo-retailcrm/include/class-wc-retailcrm-base.php index d43a1dd1..95b00f38 100644 --- a/woo-retailcrm/include/class-wc-retailcrm-base.php +++ b/woo-retailcrm/include/class-wc-retailcrm-base.php @@ -103,12 +103,47 @@ public function init_form_fields() { if ($this->get_option( 'api_url' ) != '' && $this->get_option( 'api_key' ) != '') { if (isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'integration') { + add_action('admin_print_footer_scripts', array($this, 'show_blocks'), 99); + $retailcrm = new WC_Retailcrm_Proxy( $this->get_option( 'api_url' ), $this->get_option( 'api_key' ), $this->get_option( 'api_version') ); + /** + * Order methods options + */ + $order_methods_option = array(); + $order_methods_list = $retailcrm->orderMethodsList(); + + if ($order_methods_list->isSuccessful()) { + foreach ($order_methods_list['orderMethods'] as $order_method) { + if ($order_method['active'] == false) { + continue; + } + + $order_methods_option[$order_method['code']] = $order_method['name']; + } + + $this->form_fields[] = array( + 'title' => __( 'Способы оформления заказа', 'woocommerce' ), + 'type' => 'heading', + 'description' => '', + 'id' => 'order_methods_options' + ); + + $this->form_fields['order_methods'] = array( + 'label' => __( ' ', 'textdomain' ), + 'title' => 'Способы оформления заказа, доступные для выгрузки из RetailCRM', + 'class' => '', + 'type' => 'multiselect', + 'description' => 'Выберите способы оформления для заказов, которые будут выгружаться из RetailCRM на сайт', + 'options' => $order_methods_option, + 'select_buttons' => true + ); + } + /** * Shipping options */ @@ -124,7 +159,7 @@ public function init_form_fields() { $this->form_fields[] = array( 'title' => __( 'Способы доставки', 'woocommerce' ), - 'type' => 'title', + 'type' => 'heading', 'description' => '', 'id' => 'shipping_options' ); @@ -159,7 +194,7 @@ public function init_form_fields() { $this->form_fields[] = array( 'title' => __( 'Способы оплаты', 'woocommerce' ), - 'type' => 'title', + 'type' => 'heading', 'description' => '', 'id' => 'payment_options' ); @@ -196,7 +231,7 @@ public function init_form_fields() { $this->form_fields[] = array( 'title' => __( 'Статусы', 'woocommerce' ), - 'type' => 'title', + 'type' => 'heading', 'description' => '', 'id' => 'statuses_options' ); @@ -219,7 +254,7 @@ public function init_form_fields() { */ $this->form_fields[] = array( 'title' => __( 'Настройки выгрузки остатков', 'woocommerce' ), - 'type' => 'title', + 'type' => 'heading', 'description' => '', 'id' => 'invent_options' ); @@ -240,7 +275,7 @@ public function init_form_fields() { if (!isset($options['uploads'])) { $this->form_fields[] = array( 'title' => __( 'Выгрузка клиентов и заказов', 'woocommerce' ), - 'type' => 'title', + 'type' => 'heading', 'description' => '', 'id' => 'upload_options' ); @@ -277,6 +312,14 @@ public function init_form_fields() { } } + /** + * Generate html button + * + * @param string $key + * @param array $data + * + * @return string + */ public function generate_button_html( $key, $data ) { $field = $this->plugin_id . $this->id . '_' . $key; $defaults = array( @@ -309,6 +352,44 @@ public function generate_button_html( $key, $data ) { return ob_get_clean(); } + /** + * Generate html title block settings + * + * @param string $key + * @param array $data + * + * @return string + */ + public function generate_heading_html($key, $data) { + $field_key = $this->get_field_key( $key ); + $defaults = array( + 'title' => '', + 'class' => '', + ); + + $data = wp_parse_args( $data, $defaults ); + + ob_start(); + ?> + +

+ +

+ + + get_post_data(); @@ -334,6 +415,14 @@ public function validate_api_version_field( $key, $value ) { } } + /** + * Validate API url + * + * @param string $key + * @param string $value + * + * @return string + */ public function validate_api_url_field( $key, $value ) { $post = $this->get_post_data(); $api = new WC_Retailcrm_Proxy( @@ -350,7 +439,15 @@ public function validate_api_url_field( $key, $value ) { return $value; } - + + /** + * Validate API key + * + * @param string $key + * @param string $value + * + * @return string + */ public function validate_api_key_field( $key, $value ) { $post = $this->get_post_data(); $api = new WC_Retailcrm_Proxy( @@ -371,6 +468,30 @@ public function validate_api_key_field( $key, $value ) { return $value; } + + /** + * Scritp show|hide block settings + */ + function show_blocks() { + ?> + + retailcrm_settings = get_option( 'woocommerce_integration-retailcrm_settings' ); + if (isset($this->retailcrm_settings['order_methods'])) { + $this->order_methods = $this->retailcrm_settings['order_methods']; + unset($this->retailcrm_settings['order_methods']); + } + if ( ! class_exists( 'WC_Retailcrm_Proxy' ) ) { include_once( WP_PLUGIN_DIR . '/woo-retailcrm/include/api/class-wc-retailcrm-proxy.php' ); } @@ -37,78 +47,103 @@ public function __construct() $this->startDateCustomers = $this->startDate; } + /** + * Get history method + * + * @return void + */ public function getHistory() { - if (isset($this->retailcrm_settings['history_orders'])) { + $orders_since_id = get_option('retailcrm_orders_history_since_id'); + $customers_since_id = get_option('retailcrm_customers_history_since_id'); + + if (!$orders_since_id && isset($this->retailcrm_settings['history_orders'])) { $this->startDateOrders = new DateTime($this->retailcrm_settings['history_orders']); } - if (isset($this->retailcrm_settings['history_customers'])) { + if (!$customers_since_id && isset($this->retailcrm_settings['history_customers'])) { $this->startDateCustomers = new DateTime($this->retailcrm_settings['history_orders']); } - $this->ordersHistory($this->startDateOrders->format('Y-m-d H:i:s')); - - $this->customersHistory($this->startDateCustomers->format('Y-m-d H:i:s')); + $this->customersHistory($this->startDateCustomers->format('Y-m-d H:i:s'), $customers_since_id); + $this->ordersHistory($this->startDateOrders->format('Y-m-d H:i:s'), $orders_since_id); } - protected function customersHistory($date) + /** + * History customers + * + * @param string $date + * @param int $since_id + * + * @return null + */ + protected function customersHistory($date, $since_id) { - $response = $this->retailcrm->customersHistory(array('startDate' => $date)); + if ($since_id) { + $response = $this->retailcrm->customersHistory(array('sinceId' => $since_id)); + } else { + $response = $this->retailcrm->customersHistory(array('startDate' => $date)); + } if ($response->isSuccessful()) { - $generatedAt = $response->generatedAt; + if (empty($response['history'])) { + return; + } - foreach ($response['history'] as $record) { + $history = $response['history']; + $end_change = end($history); + $new_since_id = $end_change['id']; + + foreach ($history as $record) { if ($record['source'] == 'api' && $record['apiKey']['current'] == true) { continue; } $this->removeFuncsHook(); - if ($record['field'] == 'first_name' && $record['customer']['externalId']) { + if ($record['field'] == 'first_name' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'first_name', $record['newValue']); } } - elseif ($record['field'] == 'last_name' && $record['customer']['externalId']) { + elseif ($record['field'] == 'last_name' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'last_name', $record['newValue']); } } - elseif ($record['field'] == 'email' && $record['customer']['externalId']) { + elseif ($record['field'] == 'email' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_email', $record['newValue']); } } - elseif ($record['field'] == 'phones' && $record['customer']['externalId']) { + elseif ($record['field'] == 'phones' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_phone', $record['newValue']); } } - elseif ($record['field'] == 'address.region' && $record['customer']['externalId']) { + elseif ($record['field'] == 'address.region' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_state', $record['newValue']); } } - elseif ($record['field'] == 'address.index' && $record['customer']['externalId']) { + elseif ($record['field'] == 'address.index' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_postcode', $record['newValue']); } } - elseif ($record['field'] == 'address.country' && $record['customer']['externalId']) { + elseif ($record['field'] == 'address.country' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_country', $record['newValue']); } } - elseif ($record['field'] == 'address.city' && $record['customer']['externalId']) { + elseif ($record['field'] == 'address.city' && isset($record['customer']['externalId'])) { if ($record['newValue']){ update_user_meta($record['customer']['externalId'], 'billing_city', $record['newValue']); } @@ -122,20 +157,37 @@ protected function customersHistory($date) return; } - $this->retailcrm_settings['history_customers'] = $generatedAt; - update_option('woocommerce_integration-retailcrm_settings', $this->retailcrm_settings); + update_option('retailcrm_customers_history_since_id', $new_since_id); } - protected function ordersHistory($date) + /** + * History orders + * + * @param string $date + * @param int $since_id + * + * @return null + */ + protected function ordersHistory($date, $since_id) { $options = array_flip(array_filter($this->retailcrm_settings)); - $response = $this->retailcrm->ordersHistory(array('startDate' => $date)); + if ($since_id) { + $response = $this->retailcrm->ordersHistory(array('sinceId' => $since_id)); + } else { + $response = $this->retailcrm->ordersHistory(array('startDate' => $date)); + } if ($response->isSuccessful()) { - $generatedAt = $response->generatedAt; + if (empty($response['history'])) { + return; + } + + $history = $response['history']; + $end_change = end($history); + $new_since_id = $end_change['id']; - foreach ($response['history'] as $record) { + foreach ($history as $record) { if ($record['source'] == 'api' && $record['apiKey']['current'] == true) { continue; } @@ -159,11 +211,14 @@ protected function ordersHistory($date) return; } - $this->retailcrm_settings['history_orders'] = $generatedAt; - update_option('woocommerce_integration-retailcrm_settings', $this->retailcrm_settings); - + update_option('retailcrm_orders_history_since_id', $new_since_id); } + /** + * Remove function hooks before download history changes + * + * @return void + */ protected function removeFuncsHook() { if (version_compare(get_option('woocommerce_db_version'), '3.0', '<' )) { @@ -178,6 +233,11 @@ protected function removeFuncsHook() } } + /** + * Add function hooks after downloading history changes + * + * @return void + */ protected function addFuncsHook() { if (version_compare(get_option('woocommerce_db_version'), '3.0', '<' )) { @@ -209,6 +269,13 @@ protected function addFuncsHook() } } + /** + * Edit order in WC + * + * @param array $record + * @param array $options + * @return void + */ protected function orderEdit($record, $options) { if ($record['field'] == 'status' && !empty($record['newValue']) && !empty($record['oldValue'])) { @@ -370,20 +437,30 @@ protected function orderEdit($record, $options) } } - elseif (isset($record['created']) && - $record['created'] == 1 && - !isset($record['order']['externalId'])) { + elseif (isset($record['created']) + && $record['created'] == 1 + && !isset($record['order']['externalId']) + ) { + if (is_array($this->order_methods) + && $this->order_methods + && isset($record['order']['orderMethod']) + && !in_array($record['order']['orderMethod'], $this->order_methods) + ) { + return; + } $args = array( - 'status' => $options[$record['order']['status']], + 'status' => isset($options[$record['order']['status']]) ? + isset($options[$record['order']['status']]) : + 'processing', 'customer_id' => isset($record['order']['customer']['externalId']) ? - $record['order']['customer']['externalId'] : - null + $record['order']['customer']['externalId'] : + null ); $order_record = $record['order']; $order_data = wc_create_order($args); - $order = new WC_Order($order_data->id); + $order = new WC_Order($order_data->get_id()); $address_shipping = array( 'first_name' => $order_record['firstName'], @@ -398,6 +475,7 @@ protected function orderEdit($record, $options) 'postcode' => isset($order_record['delivery']['address']['postcode']) ? $order_record['delivery']['address']['postcode'] : '', 'country' => $order_record['delivery']['address']['countryIso'] ); + $address_billing = array( 'first_name' => $order_record['customer']['firstName'], 'last_name' => isset($order_record['customer']['lastName']) ? $order_record['customer']['lastName'] : '', @@ -418,18 +496,20 @@ protected function orderEdit($record, $options) if (count($order_record['payments']) == 1) { $payment_types = $payment->get_available_payment_gateways(); - $paymentType = end($order_record['payments']); + $payments = $order_record['payments']; + $paymentType = end($payments); - if (isset($payment_types[$options[$paymentType['type']]])) { + if (isset($options[$paymentType['type']]) && isset($payment_types[$options[$paymentType['type']]])) { $order->set_payment_method($payment_types[$options[$paymentType['type']]]); } } } } else { - if ($order_record['paymentType']) { + if (isset($order_record['paymentType']) && $order_record['paymentType']) { $payment = new WC_Payment_Gateways(); $payment_types = $payment->get_available_payment_gateways(); - if (isset($payment_types[$options[$order_record['paymentType']]])) { + + if (isset($options[$order_record['paymentType']]) && isset($payment_types[$options[$order_record['paymentType']]])) { $order->set_payment_method($payment_types[$options[$order_record['paymentType']]]); } } @@ -456,37 +536,39 @@ protected function orderEdit($record, $options) } } - if (isset($instance_id)) { - $wc_shipping = WC_Shipping_Zones::get_shipping_method($instance_id); - $shipping_method_title = $wc_shipping->method_title; - $shipping_method_id = $options[$deliveryCode]; - $shipping_total = $order_record['delivery']['cost']; - } else { - $wc_shipping = new WC_Shipping(); - $wc_shipping_types = $wc_shipping->get_shipping_methods(); - - foreach ($wc_shipping_types as $shipping_type) { - if ($shipping_type->id == $options[$deliveryCode]) { - $shipping_method_id = $shipping_type->id; - $shipping_method_title = $shipping_type->method_title; - $shipping_total = $order_record['delivery']['cost']; + if (isset($options[$deliveryCode])) { + if (isset($instance_id)) { + $wc_shipping = WC_Shipping_Zones::get_shipping_method($instance_id); + $shipping_method_title = $wc_shipping->method_title; + $shipping_method_id = $options[$deliveryCode]; + $shipping_total = $order_record['delivery']['cost']; + } else { + $wc_shipping = new WC_Shipping(); + $wc_shipping_types = $wc_shipping->get_shipping_methods(); + + foreach ($wc_shipping_types as $shipping_type) { + if ($shipping_type->id == $options[$deliveryCode]) { + $shipping_method_id = $shipping_type->id; + $shipping_method_title = $shipping_type->method_title; + $shipping_total = $order_record['delivery']['cost']; + } } } - } - if (version_compare(get_option('woocommerce_db_version'), '3.0', '<' )) { - $shipping_rate = new WC_Shipping_Rate($shipping_method_id, isset($shipping_method_title) ? $shipping_method_title : '', isset($shipping_total) ? floatval($shipping_total) : 0, array(), $shipping_method_id); - $order->add_shipping($shipping_rate); - } else { - $shipping = new WC_Order_Item_Shipping(); - $shipping->set_props( array( - 'method_title' => $shipping_method_title, - 'method_id' => $shipping_method_id, - 'total' => wc_format_decimal($shipping_total), - 'order_id' => $order->id - ) ); - $shipping->save(); - $order->add_item( $shipping ); + if (version_compare(get_option('woocommerce_db_version'), '3.0', '<' )) { + $shipping_rate = new WC_Shipping_Rate($shipping_method_id, isset($shipping_method_title) ? $shipping_method_title : '', isset($shipping_total) ? floatval($shipping_total) : 0, array(), $shipping_method_id); + $order->add_shipping($shipping_rate); + } else { + $shipping = new WC_Order_Item_Shipping(); + $shipping->set_props( array( + 'method_title' => $shipping_method_title, + 'method_id' => $shipping_method_id, + 'total' => wc_format_decimal($shipping_total), + 'order_id' => $order->get_id() + ) ); + $shipping->save(); + $order->add_item( $shipping ); + } } } @@ -494,13 +576,20 @@ protected function orderEdit($record, $options) $ids[] = array( 'id' => (int)$order_record['id'], - 'externalId' => (int)$order_data->id + 'externalId' => (int)$order_data->get_id() ); $this->retailcrm->ordersFixExternalIds($ids); } } + /** + * Get shipping + * + * @param array $items + * + * @return int + */ protected function getShippingItemId($items) { if ($items) { @@ -512,7 +601,13 @@ protected function getShippingItemId($items) return $item_id[0]; } - + /** + * Calculate totals in order + * + * @param type $order + * + * @return void + */ protected function update_total($order) { $order->calculate_totals(); diff --git a/woo-retailcrm/include/class-wc-retailcrm-icml.php b/woo-retailcrm/include/class-wc-retailcrm-icml.php index 09aeb057..5f0adb0e 100644 --- a/woo-retailcrm/include/class-wc-retailcrm-icml.php +++ b/woo-retailcrm/include/class-wc-retailcrm-icml.php @@ -304,7 +304,10 @@ public static function filterRecursive($haystack) $haystack[$key] = self::filterRecursive($haystack[$key]); } - if (is_null($haystack[$key]) || $haystack[$key] === '' || count($haystack[$key]) == 0) { + if (is_null($haystack[$key]) + || $haystack[$key] === '' + || (is_array($haystack[$key]) && count($haystack[$key]) == 0) + ) { unset($haystack[$key]); } elseif (!is_array($value)) { $haystack[$key] = trim($value); @@ -317,7 +320,7 @@ public static function filterRecursive($haystack) /** * Get WC products * - * @return array + * @return void */ private function get_wc_products_taxonomies($status_args) { if (!$status_args) { @@ -348,28 +351,19 @@ private function get_wc_products_taxonomies($status_args) { while ($loop->have_posts()) : $loop->the_post(); $theid = get_the_ID(); + $post = get_post($theid); - if ( version_compare( get_option( 'woocommerce_db_version' ), '3.0', '<' ) ) { - $product = new WC_Product($theid); - $parent = new WC_Product($product->get_parent()); - } - else { - $post = get_post($theid); - - if (get_post_type($theid) == 'product') { + if (get_post_type($theid) == 'product') { + $product = wc_get_product($theid); + $parent = false; + } elseif (get_post_type($theid) == 'product_variation') { + if (get_post($post->post_parent)) { $product = wc_get_product($theid); - $parent = false; + $parent = wc_get_product($product->get_parent_id()); } - elseif (get_post_type($theid) == 'product_variation') { - - if (get_post($post->post_parent)) { - $product = wc_get_product($theid); - $parent = wc_get_product($product->get_parent_id()); - } - } } - if ($product->get_type() == 'variable') { + if ($product->get_type() == 'variable') { continue; } @@ -457,7 +451,7 @@ private function get_wc_products_taxonomies($status_args) { if (isset($product_data)) { $full_product_list[] = $product_data; } - + unset($product_data); } endwhile; diff --git a/woo-retailcrm/include/class-wc-retailcrm-orders.php b/woo-retailcrm/include/class-wc-retailcrm-orders.php index 32660a46..3fe5c76e 100644 --- a/woo-retailcrm/include/class-wc-retailcrm-orders.php +++ b/woo-retailcrm/include/class-wc-retailcrm-orders.php @@ -128,9 +128,15 @@ public function orderUpdateStatus($order_id) { * Update order payment type * * @param $order_id + * + * @return null */ public function orderUpdatePaymentType($order_id, $payment_method) { + if (!isset($this->retailcrm_settings[$payment_method])) { + return; + } + if ($this->retailcrm_settings['api_version'] != 'v5') { $order_data = array( 'externalId' => $order_id, @@ -141,7 +147,9 @@ public function orderUpdatePaymentType($order_id, $payment_method) { } else { $response = $this->retailcrm->ordersGet($order_id); - if ($response->isSuccessful()) $order = $response['order']; + if ($response->isSuccessful()) { + $order = $response['order']; + } foreach ($order['payments'] as $payment_data) { if ($payment_data['externalId'] == $order_id) { @@ -300,7 +308,8 @@ public function processOrder($order_id, $update = false) } if ($order->get_items( 'shipping' )) { - $shipping = end($order->get_items( 'shipping' )); + $shippings = $order->get_items( 'shipping' ); + $shipping = end($shippings); $shipping_code = explode(':', $shipping['method_id']); if (isset($this->retailcrm_settings[$shipping['method_id']])) { @@ -489,7 +498,7 @@ public function updateOrder($order_id) $orderWc = new WC_Order($order_id); if ($response->isSuccessful()) { - $this->orderUpdatePaymentType($order_id, $orderWc->payment_method); + $this->orderUpdatePaymentType($order_id, $orderWc->get_payment_method()); } } } diff --git a/woo-retailcrm/retailcrm.php b/woo-retailcrm/retailcrm.php index c2c88ac7..70ffcf91 100644 --- a/woo-retailcrm/retailcrm.php +++ b/woo-retailcrm/retailcrm.php @@ -1,6 +1,6 @@