diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php index 7fb8cb5..95be386 100644 --- a/src/include/class-wc-retailcrm-base.php +++ b/src/include/class-wc-retailcrm-base.php @@ -206,11 +206,33 @@ if (!class_exists('WC_Retailcrm_Base')) { $ids = false; 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_merge($ids, $appendix); } if ($ids) { - $this->orders->ordersUpload($ids, true); + $this->orders->ordersUpload(array_unique($ids), true); } } diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index 00feb7c..81c33d0 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -89,25 +89,6 @@ if (!class_exists('WC_Retailcrm_Customers')) : return $this->retailcrm->getCorporateEnabled(); } - /** - * Returns true if provided customer has company name in billing address. - * Note: customer can have company name in address which was added after synchronization. - * In that case customer will not be corporate, but this method will return true. - * - * @param \WC_Customer $customer - * - * @return bool - */ - public static function customerPossiblyCorporate($customer) - { - if (!($customer instanceof WC_Customer)) { - return false; - } - - return !empty($customer->get_billing_company()); - } - - /** * Upload customers to CRM * @@ -125,7 +106,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : $data_customers = array(); foreach ($users as $user) { - if (!\in_array(self::CUSTOMER_ROLE, $user->roles)) { + if (!static::isCustomer($user)) { continue; } @@ -165,7 +146,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : return null; } - if ($customer->get_role() == self::CUSTOMER_ROLE) { + if (self::isCustomer($customer)) { $this->processCustomer($customer); $response = $this->retailcrm->customersCreate($this->customer); @@ -192,7 +173,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : $customer = $this->wcCustomerGet($customer_id); - if ($customer->get_role() == self::CUSTOMER_ROLE) { + if (self::isCustomer($customer)) { $this->processCustomer($customer); $this->retailcrm->customersEdit($this->customer); } @@ -224,7 +205,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : return null; } - if ($customer->get_role() == self::CUSTOMER_ROLE) { + if (self::isCustomer($customer)) { $this->processCorporateCustomer($crmCustomerId, $customer, $order); $response = $this->retailcrm->customersCorporateCreate($this->customerCorporate); @@ -324,7 +305,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : ); $data_customer = array( - 'nickName' => $customer->get_billing_company(), + 'nickName' => $order->get_billing_company(), 'contact' => array( 'id' => $crmCustomerId, 'isMain' => true @@ -407,10 +388,11 @@ if (!class_exists('WC_Retailcrm_Customers')) : * Search by provided filter, returns first found customer * * @param array $filter + * @param bool $returnGroup Return all customers for group filter instead of first * * @return bool|array */ - public function searchCorporateCustomer($filter) + public function searchCorporateCustomer($filter, $returnGroup = false) { if (isset($filter['externalId'])) { $search = $this->retailcrm->customersCorporateGet($filter['externalId']); @@ -426,7 +408,11 @@ if (!class_exists('WC_Retailcrm_Customers')) : return false; } - $customer = reset($search['customersCorporate']); + if ($returnGroup) { + return $search['customersCorporate']; + } else { + $customer = reset($search['customersCorporate']); + } } elseif (isset($search['customerCorporate'])) { $customer = $search['customerCorporate']; } else { @@ -479,5 +465,24 @@ if (!class_exists('WC_Retailcrm_Customers')) : { return $this->customer; } + + /** + * Returns true if provided WP_User or WC_Customer should be uploaded to CRM + * + * @param \WC_Customer|\WP_User $user + * + * @return bool + */ + public static function isCustomer($user) + { + if ($user instanceof WC_Customer) { + return $user->get_role() == self::CUSTOMER_ROLE || $user->get_role() == self::ADMIN_ROLE; + } elseif ($user instanceof WP_User) { + return in_array(self::CUSTOMER_ROLE, $user->roles) + || in_array(self::ADMIN_ROLE, $user->roles); + } + + return false; + } } endif; diff --git a/src/include/class-wc-retailcrm-history.php b/src/include/class-wc-retailcrm-history.php index f922754..2025912 100644 --- a/src/include/class-wc-retailcrm-history.php +++ b/src/include/class-wc-retailcrm-history.php @@ -497,13 +497,15 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) : return false; } + if (empty($order['customer']['externalId'])) + $args = array( 'status' => isset($options[$order['status']]) ? isset($options[$order['status']]) : 'processing', 'customer_id' => isset($order['customer']['externalId']) ? $order['customer']['externalId'] - : null + : (isset($order['contact']['externalId']) ? $order['contact']['externalId'] : null) ); $wc_order = wc_create_order($args); @@ -511,65 +513,12 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) : $address = isset($order['customer']['address']) ? $order['customer']['address'] : array(); $companyName = ''; - if (isset($order['customer']['type']) && $order['customer']['type'] == 'customer_corporate') { - if (isset($order['customer']['mainCustomerContact']) - && isset($order['customer']['mainCustomerContact']['customer']['id']) - ) { - $customerResponse = $this->retailcrm->customersGet( - $order['customer']['mainCustomerContact']['customer']['id'], - 'id' - ); - - if ($customerResponse instanceof WC_Retailcrm_Response && $customerResponse->offsetExists('customer')) { - $customer = $customerResponse['customer']; - } else { - return false; - } - } else { - return false; - } - - if (isset($order['customer']['mainAddress']) && isset($order['customer']['mainAddress']['id'])) { - $response = $this->retailcrm->customersCorporateAddresses( - $order['customer']['id'], - array('ids' => array($order['customer']['mainAddress']['id'])), - null, - null, - 'id' - ); - - if ($response instanceof WC_Retailcrm_Response && $response->offsetExists('addresses')) { - $addresses = $response['addresses']; - $address = reset($addresses); - } else { - return false; - } - } else { - return false; - } - - if (isset($order['customer']['mainCompany']) && isset($order['customer']['mainCompany']['id'])) { - $response = $this->retailcrm->customersCorporateCompanies( - $order['customer']['id'], - array('ids' => array($order['customer']['mainCompany']['id'])), - null, - null, - 'id' - ); - - if ($response instanceof WC_Retailcrm_Response && $response->offsetExists('companies')) { - $companies = $response['companies']; - $company = reset($companies); - - if (isset($company['name']) && !empty($company['name'])) { - $companyName = $company['name']; - } - } else { - return false; - } - } else { - return false; - } + if (isset($order['customer']['type']) + && $order['customer']['type'] == 'customer_corporate' + && !empty($order['customer']['mainCompany']) + && isset($order['customer']['mainCompany']['name']) + ) { + $companyName = $order['customer']['mainCompany']['name']; } $address_shipping = array( diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 271c16d..05c4673 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -62,10 +62,11 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : /** * Upload orders to CRM * - * @param bool $withCustomers + * @param bool $withCustomers * @param array $include + * * @return array $uploadOrders | null - * @todo Implement correct logic for corporate customers + * @throws \Exception */ public function ordersUpload($include = array(), $withCustomers = false) { @@ -86,12 +87,24 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : 'include' => $include )); - $orders_data = array(); + $ordersData = array(); + $corporateUploadErrors = array(); foreach ($orders as $data_order) { $order = wc_get_order($data_order->ID); - $this->processOrder($order); + + if ($this->retailcrm->getCorporateEnabled() && self::isCorporateOrder($order)) { + $errorMessage = $this->orderCreate($data_order->ID); + + if (is_string($errorMessage)) { + $corporateUploadErrors[$data_order->ID] = $errorMessage; + } + + continue; + } + $customer = $order->get_user(); + $this->processOrder($order); $customers = array(); if ($customer != false) { @@ -102,7 +115,7 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } } - $orders_data[] = $this->order; + $ordersData[] = $this->order; } if ($withCustomers === true && !empty($customers)) { @@ -114,7 +127,7 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } } - $uploadOrders = array_chunk(WC_Retailcrm_Plugin::clearArray($orders_data), 50); + $uploadOrders = array_chunk(WC_Retailcrm_Plugin::clearArray($ordersData), 50); foreach ($uploadOrders as $uploadOrder) { $this->retailcrm->ordersUpload($uploadOrder); @@ -125,11 +138,11 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } /** - * Create order + * Create order. Returns wc_get_order data or error string. * * @param $order_id * - * @return mixed + * @return bool|WC_Order|WC_Order_Refund|string * @throws \Exception */ public function orderCreate($order_id) @@ -143,6 +156,10 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $wpUser = $wcOrder->get_user(); if ($wpUser instanceof WP_User) { + if (!WC_Retailcrm_Customers::isCustomer($wpUser)) { + return $wcOrder; + } + $wpUserId = (int) $wpUser->get('ID'); $this->fillOrderCreate($wpUserId, $wpUser->get('email'), $wcOrder); } else { @@ -150,7 +167,33 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : $this->fillOrderCreate(0, $wcCustomer->get_email(), $wcOrder); } - $this->retailcrm->ordersCreate($this->order); + try { + $response = $this->retailcrm->ordersCreate($this->order); + + if ($response instanceof WC_Retailcrm_Response) { + if ($response->isSuccessful()) { + return $wcOrder; + } else { + if ($response->offsetExists('error')) { + return $response['error']; + } elseif ($response->offsetExists('errors') && is_array($response['errors'])) { + $errorMessage = ''; + + foreach ($response['errors'] as $error) { + $errorMessage .= $error . ' >'; + } + + if (strlen($errorMessage) > 2) { + return substr($errorMessage, 0, strlen($errorMessage) - 2); + } + + return $errorMessage; + } + } + } + } catch (InvalidArgumentException $exception) { + return $exception->getMessage(); + } return $wcOrder; } @@ -181,14 +224,24 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } if ($this->retailcrm->getCorporateEnabled() && static::isCorporateOrder($wcOrder)) { - $crmCorporate = $this->customers->searchCorporateCustomer(array( + $crmCorporate = array(); + $crmCorporateList = $this->customers->searchCorporateCustomer(array( 'contactIds' => array($foundCustomerId) - )); + ), true); - // TODO Incorrect logic here: it makes duplicates of corporate clients. Fix that. - if (empty($crmCorporate) || (!empty($crmCorporate) - && isset($crmCorporate['mainCompany']) - && isset($crmCorporate['mainCompany']['name']) + foreach ($crmCorporateList as $corporate) { + if (!empty($corporate) + && !empty($corporate['mainCompany']) + && isset($corporate['mainCompany']['name']) + && $corporate['mainCompany']['name'] == $wcOrder->get_billing_company() + ) { + $crmCorporate = $corporate; + + break; + } + } + + if (empty($crmCorporate) || (!empty($crmCorporate['mainCompany']) && $crmCorporate['mainCompany']['name'] != $wcOrder->get_billing_company()) ) { $corporateId = $this->customers->createCorporateCustomerForOrder(