From 9e23d181d57b611c941814bea24e2f9667745055 Mon Sep 17 00:00:00 2001 From: dima-uryvskiy Date: Fri, 2 Jul 2021 19:41:06 +0300 Subject: [PATCH] Add package uploads --- src/assets/css/progress-bar.css | 27 +++ .../{whatsapp_icon.css => whatsapp-icon.css} | 0 ...app_icon.min.css => whatsapp-icon.min.css} | 0 src/assets/js/retailcrm-export.js | 125 ++++++++++ .../class-wc-retailcrm-abstracts-settings.php | 82 +++---- src/include/class-wc-retailcrm-base.php | 57 ++--- src/include/class-wc-retailcrm-customers.php | 49 ++-- src/include/class-wc-retailcrm-orders.php | 74 +----- src/include/class-wc-retailcrm-uploader.php | 213 ++++++++++++++++++ src/retailcrm.php | 2 + 10 files changed, 439 insertions(+), 190 deletions(-) create mode 100644 src/assets/css/progress-bar.css rename src/assets/css/{whatsapp_icon.css => whatsapp-icon.css} (100%) rename src/assets/css/{whatsapp_icon.min.css => whatsapp-icon.min.css} (100%) create mode 100644 src/assets/js/retailcrm-export.js create mode 100644 src/include/class-wc-retailcrm-uploader.php diff --git a/src/assets/css/progress-bar.css b/src/assets/css/progress-bar.css new file mode 100644 index 0000000..3ffc086 --- /dev/null +++ b/src/assets/css/progress-bar.css @@ -0,0 +1,27 @@ +.retail-progress { + border-radius: 18px; + border: 1px solid rgba(122, 122, 122, 0.15); + width: 400px; + height: 18px; + overflow: hidden; + transition: height 0.25s ease; +} + +.retail-progress__loader { + width: 0; + border-radius: 18px; + background: #6427D6; + color: white; + text-align: center; + padding: 0 30px; + font-size: 18px; + font-weight: 600; + transition: width 0.4s ease-in; + line-height: 18px; +} + +.retail-hidden { + display: none !important; +} + + diff --git a/src/assets/css/whatsapp_icon.css b/src/assets/css/whatsapp-icon.css similarity index 100% rename from src/assets/css/whatsapp_icon.css rename to src/assets/css/whatsapp-icon.css diff --git a/src/assets/css/whatsapp_icon.min.css b/src/assets/css/whatsapp-icon.min.css similarity index 100% rename from src/assets/css/whatsapp_icon.min.css rename to src/assets/css/whatsapp-icon.min.css diff --git a/src/assets/js/retailcrm-export.js b/src/assets/js/retailcrm-export.js new file mode 100644 index 0000000..e540e2a --- /dev/null +++ b/src/assets/js/retailcrm-export.js @@ -0,0 +1,125 @@ +jQuery(function () { + function RetailcrmExportForm() { + this.submitButton = jQuery('button[id="export-orders-submit"]').get(0); + jQuery(this.submitButton).after('
', {class: 'retail-progress__loader', text: '0%'})) + + window.addEventListener('beforeunload', this.confirmLeave); + }; + + RetailcrmExportForm.prototype.updateProgressBar = function () { + console.log('Step5'); + let processedOrders = this.ordersStep * this.ordersStepSize; + if (processedOrders > this.ordersCount) + processedOrders = this.ordersCount; + + let processedCustomers = this.customersStep * this.customersStepSize; + if (processedCustomers > this.customersCount) + processedCustomers = this.customersCount; + + const processed = processedOrders + processedCustomers; + const total = this.ordersCount + this.customersCount; + const percents = Math.round(100 * processed / total); + + jQuery(this.progressBar).find('.retail-progress__loader').text(percents + '%'); + jQuery(this.progressBar).find('.retail-progress__loader').css('width', percents + '%'); + jQuery(this.progressBar).find('.retail-progress__loader').attr('title', processed + '/' + total); + }; + + RetailcrmExportForm.prototype.confirmLeave = function (event) { + console.log('Step6'); + event.preventDefault(); + e.returnValue = 'Export process has been started'; + } + + RetailcrmExportForm.prototype.exportDone = function () { + console.log('Step7'); + window.removeEventListener('beforeunload', this.confirmLeave); + alert('Done') + } + + window.RetailcrmExportForm = RetailcrmExportForm; + console.log('before'); + if (!(typeof RetailcrmExportForm === 'undefined')) { + new window.RetailcrmExportForm(); + } + console.log('after'); +}); diff --git a/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php b/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php index d343a1e..7b6944d 100644 --- a/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php +++ b/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php @@ -23,7 +23,8 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration /** * WC_Retailcrm_Abstracts_Settings constructor. */ - public function __construct() { + public function __construct() + { $this->id = 'integration-retailcrm'; $this->method_title = __('Simla.com', 'retailcrm'); $this->method_description = __('Integration with Simla.com management system.', 'retailcrm'); @@ -35,26 +36,29 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration ) { add_action('init', array($this, 'init_settings_fields'), 99); } - } - public function ajax_upload() + // Include js scripts + $this->includeJsScripts(); + + }//end __construct() + + + /** + * In this function we include JS scripts. + * + * @return void + */ + private function includeJsScripts() { - $ajax_url = admin_url('admin-ajax.php'); - ?> - - array( 'title' => __( 'API of URL', 'retailcrm' ), 'type' => 'text', - 'description' => __( 'Enter API of URL (https://yourdomain.retailcrm.pro).', 'retailcrm' ), + 'description' => __( 'Enter API of URL (https://yourdomain.simla.com).', 'retailcrm' ), 'desc_tip' => true, 'default' => '' ), @@ -418,25 +422,23 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration /** * Uploads options */ - $options = array_filter(get_option(static::$option_key)); + $this->form_fields[] = array( + 'title' => __('Settings of uploading', 'retailcrm'), + 'type' => 'heading', + 'description' => '', + 'id' => 'upload_options' + ); - if (!isset($options['uploads'])) { - $this->form_fields[] = array( - 'title' => __('Settings of uploading', 'retailcrm'), - 'type' => 'heading', - 'description' => '', - 'id' => 'upload_options' - ); + $this->form_fields['upload-button'] = array( + 'label' => __('Upload', 'retailcrm'), + 'title' => __('Uploading all customers and orders', 'retailcrm'), + 'type' => 'button', + 'description' => __('Uploading the existing customers and orders to Simla.com', 'retailcrm'), + 'desc_tip' => true, + 'id' => 'export-orders-submit' + ); - $this->form_fields['upload-button'] = array( - 'label' => __('Upload', 'retailcrm'), - 'title' => __('Uploading all customers and orders', 'retailcrm' ), - 'type' => 'button', - 'description' => __('Uploading the existing customers and orders to Simla.com', 'retailcrm' ), - 'desc_tip' => true, - 'id' => 'uploads-retailcrm' - ); - } + //echo '
'; /** * WhatsApp options @@ -636,11 +638,11 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration public function validate_online_assistant_field($key, $value) { $onlineAssistant = $_POST['woocommerce_integration-retailcrm_online_assistant']; - + if (!empty($onlineAssistant) && is_string($onlineAssistant)) { return wp_unslash($onlineAssistant); } - + return ''; } @@ -788,4 +790,4 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration ) ); } -} +} \ No newline at end of file diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php index f157795..1928644 100644 --- a/src/include/class-wc-retailcrm-base.php +++ b/src/include/class-wc-retailcrm-base.php @@ -38,6 +38,9 @@ if (!class_exists('WC_Retailcrm_Base')) { /** @var \WC_Retailcrm_Orders */ protected $orders; + /** @var WC_Retailcrm_Uploader */ + protected $uploader; + /** * Init and hook in the integration. * @param \WC_Retailcrm_Proxy|WC_Retailcrm_Client_V4|WC_Retailcrm_Client_V5|bool $retailcrm (default = false) @@ -72,10 +75,12 @@ if (!class_exists('WC_Retailcrm_Base')) { new WC_Retailcrm_Order_Payment($this->settings) ); + $this->uploader = new WC_Retailcrm_Uploader($this->apiClient, $this->orders, $this->customers); + // Actions. add_action('woocommerce_update_options_integration_' . $this->id, array($this, 'process_admin_options')); add_filter('woocommerce_settings_api_sanitized_fields_' . $this->id, array($this, 'api_sanitized')); - add_action('admin_bar_menu', array($this, 'add_retailcrm_button'), 100 ); + add_action('admin_bar_menu', array($this, 'add_retailcrm_button'), 100); add_action('woocommerce_checkout_order_processed', array($this, 'retailcrm_process_order'), 10, 1); add_action('retailcrm_history', array($this, 'retailcrm_history_get')); add_action('retailcrm_icml', array($this, 'generate_icml')); @@ -83,7 +88,6 @@ if (!class_exists('WC_Retailcrm_Base')) { add_action('wp_ajax_do_upload', array($this, 'upload_to_crm')); add_action('wp_ajax_generate_icml', array($this, 'generate_icml')); add_action('wp_ajax_order_upload', array($this, 'order_upload')); - add_action('admin_print_footer_scripts', array($this, 'ajax_upload'), 99); add_action('admin_print_footer_scripts', array($this, 'ajax_generate_icml'), 99); add_action('admin_print_footer_scripts', array($this, 'ajax_selected_order'), 99); add_action('woocommerce_created_customer', array($this, 'create_customer'), 10, 1); @@ -225,53 +229,24 @@ if (!class_exists('WC_Retailcrm_Base')) { /** * Upload selected orders + * + * @return void */ - public function order_upload() { - $ids = false; + public function order_upload() + { + $this->uploader->uploadSelectedOrders(); - if (isset($_GET['order_ids_retailcrm'])) { - $appendix = array(); - $ids = explode(',', $_GET['order_ids_retailcrm']); - - foreach ($ids as $key => $id) { - if (stripos($id, '-') !== false) { - $idSplit = explode('-', $id); - - if (count($idSplit) == 2) { - $expanded = array(); - $first = (int) $idSplit[0]; - $last = (int) $idSplit[1]; - - for ($i = $first; $i <= $last; $i++) { - $expanded[] = $i; - } - - $appendix = array_merge($appendix, $expanded); - unset($ids[$key]); - } - } - } - - $ids = array_unique(array_merge($ids, $appendix)); - } - - if ($ids) { - $this->orders->ordersUpload($ids); - } - } + }//end order_upload() /** * Upload archive customers and order to retailCRM */ public function upload_to_crm() { - $options = array_filter(get_option(static::$option_key)); + $page = filter_input(INPUT_POST, 'RETAILCRM_EXPORT_ORDERS_STEP'); - $this->customers->customersUpload(); - $this->orders->ordersUpload(); - - $options['uploads'] = static::YES; - update_option(static::$option_key, $options); + $this->uploader->uploadArchiveCustomers($page); + $this->uploader->uploadArchiveOrders($page); } /** @@ -434,7 +409,7 @@ if (!class_exists('WC_Retailcrm_Base')) { */ public function include_whatsapp_icon_style() { - wp_register_style('whatsapp_icon_style', plugins_url() . '/woo-retailcrm/assets/css/whatsapp_icon.min.css', false, '0.1'); + wp_register_style('whatsapp_icon_style', plugins_url() . '/woo-retailcrm/assets/css/whatsapp-icon.min.css', false, '0.1'); wp_enqueue_style('whatsapp_icon_style'); } diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index 5aaa7e7..39eb236 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -90,42 +90,6 @@ if (!class_exists('WC_Retailcrm_Customers')) : return $this->retailcrm->getCorporateEnabled(); } - /** - * Upload customers to CRM - * - * @param array $ids - * - * @return array mixed - */ - public function customersUpload($ids = array()) - { - if (!$this->retailcrm) { - return null; - } - - $users = get_users(array('include' => $ids)); - $data_customers = array(); - - foreach ($users as $user) { - if (!$this->isCustomer($user)) { - continue; - } - - $customer = $this->wcCustomerGet($user->ID); - $this->processCustomer($customer); - $data_customers[] = $this->customer; - } - - $data = \array_chunk($data_customers, 50); - - foreach ($data as $array_customers) { - $this->retailcrm->customersUpload($array_customers); - time_nanosleep(0, 250000000); - } - - return $data; - } - /** * Create customer in CRM * @@ -335,6 +299,19 @@ if (!class_exists('WC_Retailcrm_Customers')) : return $customerId; } + /** + * Process customer for upload + * + * @param WC_Customer $customer + * + * @return void + */ + public function processCustomerForUpload($customer) + { + $this->processCustomer($customer); + }//end processCustomerForUpload() + + /** * Process customer * diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 67ce678..d176461 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -62,56 +62,6 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $this->order_payment = $order_payment; } - /** - * Upload orders to CRM - * - * @param array $include - * - * @return array $uploadOrders | null - * @throws \Exception - */ - public function ordersUpload($include = array()) - { - if (!$this->retailcrm) { - return null; - } - - $uploader = new WC_Retailcrm_Customers( - $this->retailcrm, - $this->retailcrm_settings, - new WC_Retailcrm_Customer_Address() - ); - - $orders = get_posts(array( - 'numberposts' => -1, - 'post_type' => wc_get_order_types('view-orders'), - 'post_status' => array_keys(wc_get_order_statuses()), - 'include' => $include - )); - - $regularUploadErrors = array(); - $corporateUploadErrors = array(); - - foreach ($orders as $data_order) { - $order = wc_get_order($data_order->ID); - - $errorMessage = $this->orderCreate($data_order->ID); - - if (is_string($errorMessage)) { - if ($this->retailcrm->getCorporateEnabled() && self::isCorporateOrder($order)) { - $corporateUploadErrors[$data_order->ID] = $errorMessage; - } else { - $regularUploadErrors[$data_order->ID] = $errorMessage; - } - } - } - - static::logOrdersUploadErrors($regularUploadErrors, 'Error while uploading these regular orders'); - static::logOrdersUploadErrors($corporateUploadErrors, 'Error while uploading these corporate orders'); - - return array(); - } - /** * Create order. Returns wc_get_order data or error string. * @@ -599,27 +549,5 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : return $customerWasChanged; } - - /** - * Logs orders upload errors with prefix log message. - * Array keys must be orders ID's in WooCommerce, values must be strings (error messages). - * - * @param array $errors - * @param string $prefix - */ - public static function logOrdersUploadErrors($errors, $prefix = 'Errors while uploading these orders') - { - if (empty($errors)) { - return; - } - - WC_Retailcrm_Logger::add($prefix); - - foreach ($errors as $orderId => $error) { - WC_Retailcrm_Logger::add(sprintf("[%d] => %s", $orderId, $error)); - } - - WC_Retailcrm_Logger::add('=================================='); - } } -endif; +endif; \ No newline at end of file diff --git a/src/include/class-wc-retailcrm-uploader.php b/src/include/class-wc-retailcrm-uploader.php new file mode 100644 index 0000000..2d05ccb --- /dev/null +++ b/src/include/class-wc-retailcrm-uploader.php @@ -0,0 +1,213 @@ +retailcrm = $retailcrm; + $this->orders = $orders; + $this->customers = $customers; + + }//end __construct() + + + /** + * Uploads selected order in CRM + * + * @return void + * @throws Exception Invalid argument exception. + */ + public function uploadSelectedOrders() + { + $response = filter_input(INPUT_GET, 'order_ids_retailcrm'); + + if (empty($response) === false) { + $ids = array_unique(explode(',', $response)); + + if (empty($ids) === false) { + $this->uploadArchiveOrders(0, $ids); + } + } + + }//end uploadSelectedOrders() + + + /** + * Uploads archive order in CRM + * + * @param integer $page Number page uploads. + * @param array $ids Ids orders upload. + * + * @return void + * @throws Exception Invalid argument exception. + */ + public function uploadArchiveOrders($page, $ids=array()) + { + if (is_object($this->retailcrm) === false) { + return; + } + + $uploadErrors = array(); + $ordersCms = $this->getCmsOrders($page, $ids); + + foreach ($ordersCms as $dataOrder) { + $orderId = $dataOrder->ID; + $errorMessage = $this->orders->orderCreate($orderId); + + if (is_string($errorMessage) === true) { + $errorMessage = empty($errorMessage) === true ? 'Order exist. External id: ' . $orderId : $errorMessage; + $uploadErrors[$orderId] = $errorMessage; + } + } + + $this->logOrdersUploadErrors($uploadErrors); + + }//end uploadArchiveOrders() + + + /** + * Uploads archive customer in CRM + * + * @param integer $page Number page uploads. + * + * @return void + * @throws Exception Invalid argument exception. + */ + public function uploadArchiveCustomers($page) + { + if (is_object($this->retailcrm) === false) { + return; + } + + $users = $this->getCmsUsers($page); + + if (empty($users) === false) { + $dataCustomers = array(); + + foreach ($users as $user) { + if ($this->customers->isCustomer($user) === false) { + continue; + } + + $customer = new WC_Customer($user->ID); + $this->customers->processCustomerForUpload($customer); + $dataCustomers[] = $this->customers->getCustomer(); + } + + $this->retailcrm->customersUpload($dataCustomers); + }//end if + + }//end uploadArchiveCustomers() + + + /** + * Return orders ids + * + * @param integer $page Number page uploads. + * @param array $ids Ids orders upload. + * + * @return mixed + */ + private function getCmsOrders($page, $ids=array()) + { + return get_posts( + array( + 'numberposts' => self::RETAILCRM_COUNT_OBJECT_UPLOAD, + 'offset' => self::RETAILCRM_COUNT_OBJECT_UPLOAD * $page, + 'post_type' => wc_get_order_types('view-orders'), + 'post_status' => array_keys(wc_get_order_statuses()), + 'include' => $ids, + ) + ); + + }//end getOrderIds() + + + /** + * Return users ids + * + * @param integer $page Number page uploads. + * + * @return mixed + */ + private function getCmsUsers($page) + { + return get_users( + array( + 'number' => self::RETAILCRM_COUNT_OBJECT_UPLOAD, + 'offset' => self::RETAILCRM_COUNT_OBJECT_UPLOAD * $page, + ) + ); + + }//end getCmsUsers() + + + /** + * Array keys must be orders ID's in WooCommerce, values must be strings (error messages). + * + * @param array $errors Id order - key and message error - value. + * + * @return void + */ + private function logOrdersUploadErrors($errors) + { + if (empty($errors) === true) { + return; + } + + WC_Retailcrm_Logger::add('Errors while uploading these orders'); + + foreach ($errors as $orderId => $error) { + WC_Retailcrm_Logger::add(sprintf("[%d] => %s", $orderId, $error)); + } + + WC_Retailcrm_Logger::add('=================================='); + + }//end logOrdersUploadErrors() + + + }//end class + +}//end if diff --git a/src/retailcrm.php b/src/retailcrm.php index 46ff7f3..b4e181e 100644 --- a/src/retailcrm.php +++ b/src/retailcrm.php @@ -122,7 +122,9 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : require_once(self::checkCustomFile('include/class-wc-retailcrm-ga.php')); require_once(self::checkCustomFile('include/class-wc-retailcrm-daemon-collector.php')); require_once(self::checkCustomFile('include/class-wc-retailcrm-base.php')); + require_once(self::checkCustomFile('include/class-wc-retailcrm-uploader.php')); require_once(self::checkCustomFile('include/functions.php')); + } /**