AfterAddressSaveObserver.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Observer;
  7. use Magento\Customer\Api\GroupManagementInterface;
  8. use Magento\Customer\Helper\Address as HelperAddress;
  9. use Magento\Customer\Model\Address;
  10. use Magento\Customer\Model\Address\AbstractAddress;
  11. use Magento\Customer\Model\Session as CustomerSession;
  12. use Magento\Customer\Model\Vat;
  13. use Magento\Framework\App\Area;
  14. use Magento\Framework\App\Config\ScopeConfigInterface;
  15. use Magento\Framework\App\State as AppState;
  16. use Magento\Framework\DataObject;
  17. use Magento\Framework\Escaper;
  18. use Magento\Framework\Event\ObserverInterface;
  19. use Magento\Framework\Message\ManagerInterface;
  20. use Magento\Framework\Registry;
  21. use Magento\Store\Model\ScopeInterface;
  22. /**
  23. * Customer Observer Model
  24. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  25. */
  26. class AfterAddressSaveObserver implements ObserverInterface
  27. {
  28. /**
  29. * VAT ID validation processed flag code
  30. */
  31. const VIV_PROCESSED_FLAG = 'viv_after_address_save_processed';
  32. /**
  33. * @var HelperAddress
  34. */
  35. protected $_customerAddress;
  36. /**
  37. * @var Registry
  38. */
  39. protected $_coreRegistry;
  40. /**
  41. * @var Vat
  42. */
  43. protected $_customerVat;
  44. /**
  45. * @var GroupManagementInterface
  46. */
  47. protected $_groupManagement;
  48. /**
  49. * @var AppState
  50. */
  51. protected $appState;
  52. /**
  53. * @var ScopeConfigInterface
  54. */
  55. protected $scopeConfig;
  56. /**
  57. * @var ManagerInterface
  58. */
  59. protected $messageManager;
  60. /**
  61. * @var Escaper
  62. */
  63. protected $escaper;
  64. /**
  65. * @var CustomerSession
  66. */
  67. private $customerSession;
  68. /**
  69. * @param Vat $customerVat
  70. * @param HelperAddress $customerAddress
  71. * @param Registry $coreRegistry
  72. * @param GroupManagementInterface $groupManagement
  73. * @param ScopeConfigInterface $scopeConfig
  74. * @param ManagerInterface $messageManager
  75. * @param Escaper $escaper
  76. * @param AppState $appState
  77. * @param CustomerSession $customerSession
  78. */
  79. public function __construct(
  80. Vat $customerVat,
  81. HelperAddress $customerAddress,
  82. Registry $coreRegistry,
  83. GroupManagementInterface $groupManagement,
  84. ScopeConfigInterface $scopeConfig,
  85. ManagerInterface $messageManager,
  86. Escaper $escaper,
  87. AppState $appState,
  88. CustomerSession $customerSession
  89. ) {
  90. $this->_customerVat = $customerVat;
  91. $this->_customerAddress = $customerAddress;
  92. $this->_coreRegistry = $coreRegistry;
  93. $this->_groupManagement = $groupManagement;
  94. $this->scopeConfig = $scopeConfig;
  95. $this->messageManager = $messageManager;
  96. $this->escaper = $escaper;
  97. $this->appState = $appState;
  98. $this->customerSession = $customerSession;
  99. }
  100. /**
  101. * Address after save event handler
  102. *
  103. * @param \Magento\Framework\Event\Observer $observer
  104. * @return void
  105. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  106. */
  107. public function execute(\Magento\Framework\Event\Observer $observer)
  108. {
  109. /** @var $customerAddress Address */
  110. $customerAddress = $observer->getCustomerAddress();
  111. $customer = $customerAddress->getCustomer();
  112. if (!$this->_customerAddress->isVatValidationEnabled($customer->getStore())
  113. || $this->_coreRegistry->registry(self::VIV_PROCESSED_FLAG)
  114. || !$this->_canProcessAddress($customerAddress)
  115. ) {
  116. return;
  117. }
  118. try {
  119. $this->_coreRegistry->register(self::VIV_PROCESSED_FLAG, true);
  120. if ($customerAddress->getVatId() == ''
  121. || !$this->_customerVat->isCountryInEU($customerAddress->getCountry())
  122. ) {
  123. $defaultGroupId = $this->_groupManagement->getDefaultGroup($customer->getStore())->getId();
  124. if (!$customer->getDisableAutoGroupChange() && $customer->getGroupId() != $defaultGroupId) {
  125. $customer->setGroupId($defaultGroupId);
  126. $customer->save();
  127. $this->customerSession->setCustomerGroupId($defaultGroupId);
  128. }
  129. } else {
  130. $result = $this->_customerVat->checkVatNumber(
  131. $customerAddress->getCountryId(),
  132. $customerAddress->getVatId()
  133. );
  134. $newGroupId = $this->_customerVat->getCustomerGroupIdBasedOnVatNumber(
  135. $customerAddress->getCountryId(),
  136. $result,
  137. $customer->getStore()
  138. );
  139. if (!$customer->getDisableAutoGroupChange() && $customer->getGroupId() != $newGroupId) {
  140. $customer->setGroupId($newGroupId);
  141. $customer->save();
  142. $this->customerSession->setCustomerGroupId($newGroupId);
  143. }
  144. $customerAddress->setVatValidationResult($result);
  145. if ($this->appState->getAreaCode() == Area::AREA_FRONTEND) {
  146. if ($result->getIsValid()) {
  147. $this->addValidMessage($customerAddress, $result);
  148. } elseif ($result->getRequestSuccess()) {
  149. $this->addInvalidMessage($customerAddress);
  150. } else {
  151. $this->addErrorMessage($customerAddress);
  152. }
  153. }
  154. }
  155. } catch (\Exception $e) {
  156. $this->_coreRegistry->register(self::VIV_PROCESSED_FLAG, false, true);
  157. }
  158. }
  159. /**
  160. * Check whether specified address should be processed in after_save event handler
  161. *
  162. * @param Address $address
  163. * @return bool
  164. */
  165. protected function _canProcessAddress($address)
  166. {
  167. if ($address->getForceProcess()) {
  168. return true;
  169. }
  170. if ($this->_coreRegistry->registry(BeforeAddressSaveObserver::VIV_CURRENTLY_SAVED_ADDRESS) != $address->getId()
  171. ) {
  172. return false;
  173. }
  174. $configAddressType = $this->_customerAddress->getTaxCalculationAddressType();
  175. if ($configAddressType == AbstractAddress::TYPE_SHIPPING) {
  176. return $this->_isDefaultShipping($address);
  177. }
  178. return $this->_isDefaultBilling($address);
  179. }
  180. /**
  181. * Check whether specified billing address is default for its customer
  182. *
  183. * @param Address $address
  184. * @return bool
  185. */
  186. protected function _isDefaultBilling($address)
  187. {
  188. return $address->getId() && $address->getId() == $address->getCustomer()->getDefaultBilling()
  189. || $address->getIsPrimaryBilling()
  190. || $address->getIsDefaultBilling();
  191. }
  192. /**
  193. * Check whether specified shipping address is default for its customer
  194. *
  195. * @param Address $address
  196. * @return bool
  197. */
  198. protected function _isDefaultShipping($address)
  199. {
  200. return $address->getId() && $address->getId() == $address->getCustomer()->getDefaultShipping()
  201. || $address->getIsPrimaryShipping()
  202. || $address->getIsDefaultShipping();
  203. }
  204. /**
  205. * Add success message for valid VAT ID
  206. *
  207. * @param Address $customerAddress
  208. * @param DataObject $validationResult
  209. * @return $this
  210. */
  211. protected function addValidMessage($customerAddress, $validationResult)
  212. {
  213. $message = [
  214. (string)__('Your VAT ID was successfully validated.'),
  215. ];
  216. $customer = $customerAddress->getCustomer();
  217. if (!$this->scopeConfig->isSetFlag(HelperAddress::XML_PATH_VIV_DISABLE_AUTO_ASSIGN_DEFAULT)
  218. && !$customer->getDisableAutoGroupChange()
  219. ) {
  220. $customerVatClass = $this->_customerVat->getCustomerVatClass(
  221. $customerAddress->getCountryId(),
  222. $validationResult
  223. );
  224. $message[] = $customerVatClass == Vat::VAT_CLASS_DOMESTIC
  225. ? (string)__('You will be charged tax.')
  226. : (string)__('You will not be charged tax.');
  227. }
  228. $this->messageManager->addSuccess(implode(' ', $message));
  229. return $this;
  230. }
  231. /**
  232. * Add error message for invalid VAT ID
  233. *
  234. * @param Address $customerAddress
  235. * @return $this
  236. */
  237. protected function addInvalidMessage($customerAddress)
  238. {
  239. $vatId = $this->escaper->escapeHtml($customerAddress->getVatId());
  240. $message = [
  241. (string)__('The VAT ID entered (%1) is not a valid VAT ID.', $vatId),
  242. ];
  243. $customer = $customerAddress->getCustomer();
  244. if (!$this->scopeConfig->isSetFlag(HelperAddress::XML_PATH_VIV_DISABLE_AUTO_ASSIGN_DEFAULT)
  245. && !$customer->getDisableAutoGroupChange()
  246. ) {
  247. $message[] = (string)__('You will be charged tax.');
  248. }
  249. $this->messageManager->addError(implode(' ', $message));
  250. return $this;
  251. }
  252. /**
  253. * Add error message
  254. *
  255. * @param Address $customerAddress
  256. * @return $this
  257. */
  258. protected function addErrorMessage($customerAddress)
  259. {
  260. $message = [
  261. (string)__('Your Tax ID cannot be validated.'),
  262. ];
  263. $customer = $customerAddress->getCustomer();
  264. if (!$this->scopeConfig->isSetFlag(HelperAddress::XML_PATH_VIV_DISABLE_AUTO_ASSIGN_DEFAULT)
  265. && !$customer->getDisableAutoGroupChange()
  266. ) {
  267. $message[] = (string)__('You will be charged tax.');
  268. }
  269. $email = $this->scopeConfig->getValue('trans_email/ident_support/email', ScopeInterface::SCOPE_STORE);
  270. $message[] = (string)__('If you believe this is an error, please contact us at %1', $email);
  271. $this->messageManager->addError(implode(' ', $message));
  272. return $this;
  273. }
  274. }