diff --git a/src/include/abstracts/class-wc-retailcrm-abstracts-address.php b/src/include/abstracts/class-wc-retailcrm-abstracts-address.php index f951aec..52f6871 100644 --- a/src/include/abstracts/class-wc-retailcrm-abstracts-address.php +++ b/src/include/abstracts/class-wc-retailcrm-abstracts-address.php @@ -11,6 +11,16 @@ abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Data { + const ADDRESS_TYPE_BILLING = 'billing'; + const ADDRESS_TYPE_SHIPPING = 'shipping'; + + /** @var string $address_type */ + protected $address_type = 'shipping'; + + /** @var bool $fallback_to_billing */ + protected $fallback_to_billing = false; + + /** @var array $data */ protected $data = array( 'index' => '', 'city' => '', @@ -18,6 +28,9 @@ abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Dat 'text' => '', ); + /** + * Resets inner state + */ public function reset_data() { $this->data = array( @@ -26,6 +39,67 @@ abstract class WC_Retailcrm_Abstracts_Address extends WC_Retailcrm_Abstracts_Dat 'region' => '', 'text' => '', ); + + return $this; + } + + /** + * @param bool $fallback_to_billing + * + * @return self + */ + public function setFallbackToBilling($fallback_to_billing) + { + $this->fallback_to_billing = $fallback_to_billing; + return $this; + } + + /** + * Sets woocommerce address type to work with + * + * @param string $addressType + * + * @return self + */ + public function setWCAddressType($addressType = WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING) + { + $this->address_type = $addressType; + return $this; + } + + /** + * Returns address from order. Respects fallback_to_billing parameter. + * + * @param \WC_Order $order + * + * @return array + */ + protected function getOrderAddress($order) + { + return (empty($order->get_address($this->address_type)) && $this->fallback_to_billing) + ? $order->get_address(self::ADDRESS_TYPE_BILLING) + : $order->get_address($this->address_type); + } + + /** + * Glue two addresses + * + * @param string $address1 + * @param string $address2 + * + * @return string + */ + protected function joinAddresses($address1 = '', $address2 = '') + { + if (empty($address1) && empty($address2)) { + return ''; + } + + if (empty($address2) && !empty($address1)) { + return $address1; + } + + return $address1 . ', ' . $address2; } /** diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php index 9e8a166..eb64ba8 100644 --- a/src/include/class-wc-retailcrm-base.php +++ b/src/include/class-wc-retailcrm-base.php @@ -104,7 +104,6 @@ if (!class_exists('WC_Retailcrm_Base')) { if (!$this->get_option('deactivate_update_order') || $this->get_option('deactivate_update_order') == static::NO ) { - add_action('woocommerce_new_order', array($this, 'create_order'), 11, 1); add_action('woocommerce_update_order', array($this, 'update_order'), 11, 1); } diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index aa60214..c990ddc 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -167,6 +167,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : * @param $customer_id * * @return void|\WC_Customer + * @throws \Exception */ public function updateCustomer($customer_id) { @@ -218,6 +219,58 @@ if (!class_exists('WC_Retailcrm_Customers')) : return null; } + /** + * Create new address in corporate customer (if needed) + * + * @param int $corporateId + * @param \WC_Customer $customer + * @param \WC_Order|null $order + */ + public function fillCorporateAddress($corporateId, $customer, $order = null) + { + $found = false; + $builder = new WC_Retailcrm_Customer_Corporate_Address(); + $newAddress = $builder + ->setFallbackToBilling(true) + ->setIsMain(false) + ->setExplicitIsMain(false) + ->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING) + ->build($customer, $order) + ->get_data(); + $addresses = $this->retailcrm->customersCorporateAddresses( + $corporateId, + array(), + null, + 100, + 'id' + ); + + if ($addresses && $addresses->isSuccessful() && $addresses->offsetExists('addresses')) { + foreach ($addresses['addresses'] as $address) { + foreach ($newAddress as $field => $value) { + if (isset($address[$field]) && $address[$field] != $value) { + continue 2; + } + } + + $found = true; + + break; + } + } else { + $found = true; + } + + if (!$found) { + $this->retailcrm->customersCorporateAddressesCreate( + $corporateId, + $newAddress, + 'id', + $this->retailcrm->getSingleSiteForKey() + ); + } + } + /** * Fills corporate customer with required data after customer was created or updated. * Create or update response after sending customer must be passed. @@ -341,14 +394,35 @@ if (!class_exists('WC_Retailcrm_Customers')) : $data_customer = array( 'nickName' => $order->get_billing_company(), - 'contact' => array( - 'id' => $crmCustomerId, - 'isMain' => true + 'customerContacts' => array( + array( + 'isMain' => true, + 'customer' => array( + 'id' => $crmCustomerId + ) + ) ) ); $orderAddress = new WC_Retailcrm_Order_Address(); - $address = $orderAddress->setAddressType('billing')->build($order)->get_data(); + $corpAddress = new WC_Retailcrm_Customer_Corporate_Address(); + + $address = $orderAddress + ->setFallbackToBilling(true) + ->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_BILLING) + ->build($order) + ->get_data(); + + $shippingAddress = $corpAddress + ->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING) + ->setFallbackToBilling(true) + ->setIsMain(true) + ->build($customer, $order) + ->get_data(); + + if (isset($address['text'])) { + $data_company['contragent']['legalAddress'] = $address['text']; + } $this->customerCorporate = apply_filters( 'retailcrm_process_customer_corporate', @@ -358,7 +432,7 @@ if (!class_exists('WC_Retailcrm_Customers')) : $this->customerCorporateAddress = apply_filters( 'retailcrm_process_customer_corporate_address', WC_Retailcrm_Plugin::clearArray(array_merge( - $address, + $shippingAddress, array('isMain' => true) )), $customer diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index f947071..a5795e3 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -315,6 +315,18 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : ); $this->order['customer']['id'] = $corporateId; } else { +<<<<<<< HEAD +======= +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD + if (!empty($foundCustomer['externalId'])) { + $this->order['customer']['externalId'] = $foundCustomer['externalId']; + } else { + $this->order['customer']['id'] = $foundCustomer['id']; + } +======= +>>>>>>> new address logic & fixes $foundCustomer = $this->customers->searchCustomer(array( 'email' => $wcOrder->get_billing_email() )); @@ -328,6 +340,18 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } else { $this->order['customer']['externalId'] = $foundCustomer['externalId']; } +<<<<<<< HEAD +======= +>>>>>>> WIP: corporate customers support +======= +======= + $this->customers->fillCorporateAddress( + $crmCorporate['id'], + new WC_Customer($wcCustomerId), + $wcOrder + ); +>>>>>>> new address logic & fixes +>>>>>>> new address logic & fixes $this->order['customer']['id'] = $crmCorporate['id']; } @@ -468,7 +492,11 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) : } } - $order_data['delivery']['address'] = $this->order_address->build($order)->get_data(); + $order_data['delivery']['address'] = $this->order_address + ->setFallbackToBilling(true) + ->setWCAddressType(WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING) + ->build($order) + ->get_data(); $order_items = array(); /** @var WC_Order_Item_Product $item */ diff --git a/src/include/customer/class-wc-retailcrm-customer-corporate-address.php b/src/include/customer/class-wc-retailcrm-customer-corporate-address.php new file mode 100644 index 0000000..6bd44de --- /dev/null +++ b/src/include/customer/class-wc-retailcrm-customer-corporate-address.php @@ -0,0 +1,162 @@ + + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ + +/** + * Class WC_Retailcrm_Customer_Address + */ +class WC_Retailcrm_Customer_Corporate_Address extends WC_Retailcrm_Abstracts_Address +{ + /** @var string $filter_name */ + protected $filter_name = 'customer_address'; + + /** @var string $address_type */ + protected $address_type = 'shipping'; + + /** @var bool $fallback_to_billing */ + protected $fallback_to_billing = false; + + /** @var bool $isMain */ + protected $isMain = true; + + /** @var bool $explicitIsMain */ + protected $explicitIsMain; + + /** + * Sets woocommerce address type to work with + * + * @param string $addressType + * + * @return \WC_Retailcrm_Customer_Corporate_Address + */ + public function setWCAddressType($addressType = WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING) + { + $this->address_type = $addressType; + return $this; + } + + /** + * @param bool $fallback_to_billing + * + * @return WC_Retailcrm_Customer_Corporate_Address + */ + public function setFallbackToBilling($fallback_to_billing) + { + $this->fallback_to_billing = $fallback_to_billing; + return $this; + } + + /** + * @param bool $isMain + * + * @return WC_Retailcrm_Customer_Corporate_Address + */ + public function setIsMain($isMain) + { + $this->isMain = $isMain; + return $this; + } + + /** + * @param bool $explicitIsMain + * + * @return WC_Retailcrm_Customer_Corporate_Address + */ + public function setExplicitIsMain($explicitIsMain) + { + $this->explicitIsMain = $explicitIsMain; + return $this; + } + + /** + * @param WC_Customer $customer + * @param \WC_Order|null $order + * + * @return self + */ + public function build($customer, $order = null) + { + if ($order instanceof WC_Order) { + $address = $this->getOrderAddress($order); + $data = array( + 'index' => $address['postcode'], + 'countryIso' => $address['country'], + 'region' => $address['state'], + 'city' => $address['city'], + 'name' => $address['company'], + 'text' => $this->joinAddresses($address['address_1'], $address['address_2']) + ); + } else { + if (WC_Retailcrm_Abstracts_Address::ADDRESS_TYPE_SHIPPING == $this->address_type) { + $data = $this->getCustomerBillingAddress($customer); + + if (empty($address) && $this->fallback_to_billing) { + $data = $this->getCustomerShippingAddress($customer); + } + } else { + $data = $this->getCustomerBillingAddress($customer); + } + } + + if ($this->isMain) { + $data['isMain'] = true; + } elseif ($this->explicitIsMain) { + $data['isMain'] = false; + } + + $this->set_data_fields($data); + + return $this; + } + + /** + * Returns built customer billing address + * + * @param \WC_Customer|\WP_User $customer + * + * @return array + */ + public function getCustomerBillingAddress($customer) + { + return array( + 'index' => $customer->get_billing_postcode(), + 'countryIso' => $customer->get_billing_country(), + 'region' => $customer->get_billing_state(), + 'city' => $customer->get_billing_city(), + 'name' => $customer->get_billing_company(), + 'text' => $this->joinAddresses( + $customer->get_billing_address_1(), + $customer->get_billing_address_2() + ) + ); + } + + /** + * Returns built customer shipping address + * + * @param \WC_Customer|\WP_User $customer + * + * @return array + */ + public function getCustomerShippingAddress($customer) + { + return array( + 'index' => $customer->get_shipping_postcode(), + 'countryIso' => $customer->get_shipping_country(), + 'region' => $customer->get_shipping_state(), + 'city' => $customer->get_shipping_city(), + 'name' => $customer->get_shipping_company(), + 'text' => $this->joinAddresses( + $customer->get_shipping_address_1(), + $customer->get_shipping_address_2() + ) + ); + } +} diff --git a/src/include/order/class-wc-retailcrm-order-address.php b/src/include/order/class-wc-retailcrm-order-address.php index 0b382f6..934d468 100644 --- a/src/include/order/class-wc-retailcrm-order-address.php +++ b/src/include/order/class-wc-retailcrm-order-address.php @@ -11,22 +11,8 @@ class WC_Retailcrm_Order_Address extends WC_Retailcrm_Abstracts_Address { + /** @var string $filter_name */ protected $filter_name = 'order_address'; - protected $address_type = 'shipping'; - - /** - * Sets address type to work with - * - * @param string $addressType - * - * @return \WC_Retailcrm_Order_Address - */ - public function setAddressType($addressType = 'shipping') - { - $this->address_type = $addressType; - - return $this; - } /** * @param WC_Order $order @@ -35,7 +21,7 @@ class WC_Retailcrm_Order_Address extends WC_Retailcrm_Abstracts_Address */ public function build($order) { - $address = $order->get_address($this->address_type); + $address = $this->getOrderAddress($order); if (!empty($address)) { $data = array( diff --git a/src/retailcrm.php b/src/retailcrm.php index c81e20b..4ba1e3c 100644 --- a/src/retailcrm.php +++ b/src/retailcrm.php @@ -40,7 +40,7 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : public function __construct() { $this->load_plugin_textdomain(); - if (class_exists( 'WC_Integration' ) ) { + if (class_exists( 'WC_Integration' )) { require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-settings.php'); require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-data.php'); require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-address.php'); @@ -49,6 +49,7 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-item.php'); require_once(dirname(__FILE__ ) . '/include/order/class-wc-retailcrm-order-address.php'); require_once(dirname(__FILE__ ) . '/include/customer/class-wc-retailcrm-customer-address.php'); + require_once(dirname(__FILE__ ) . '/include/customer/class-wc-retailcrm-customer-corporate-address.php'); require_once(dirname(__FILE__ ) . '/include/class-wc-retailcrm-base.php'); require_once(dirname(__FILE__ ) . '/include/functions.php'); add_filter('woocommerce_integrations', array( $this, 'add_integration'));