AddressBuilder.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * @copyright Vertex. All rights reserved. https://www.vertexinc.com/
  4. * @author Mediotype https://www.mediotype.com/
  5. */
  6. namespace Vertex\Tax\Model\Api\Data;
  7. use Magento\Directory\Api\CountryInformationAcquirerInterface;
  8. use Magento\Directory\Api\Data\CountryInformationInterface;
  9. use Magento\Directory\Api\Data\CountryInformationInterfaceFactory;
  10. use Magento\Framework\Exception\NoSuchEntityException;
  11. use Vertex\Data\AddressInterface;
  12. use Vertex\Data\AddressInterfaceFactory;
  13. use Vertex\Tax\Model\ZipCodeFixer;
  14. /**
  15. * Builds an Address object for use with the Vertex SDK
  16. */
  17. class AddressBuilder
  18. {
  19. /** @var AddressInterfaceFactory */
  20. private $addressFactory;
  21. /** @var string */
  22. private $city;
  23. /** @var string */
  24. private $countryCode;
  25. /** @var CountryInformationAcquirerInterface */
  26. private $countryInformationAcquirer;
  27. /** @var CountryInformationInterfaceFactory */
  28. private $countryInformationFactory;
  29. /** @var string */
  30. private $postalCode;
  31. /** @var string */
  32. private $regionId;
  33. /** @var string */
  34. private $region;
  35. /** @var string[] */
  36. private $street;
  37. /** @var ZipCodeFixer */
  38. private $zipCodeFixer;
  39. /**
  40. * @param CountryInformationAcquirerInterface $countryInformationAcquirer
  41. * @param CountryInformationInterfaceFactory $countryInformationFactory
  42. * @param ZipCodeFixer $zipCodeFixer
  43. * @param AddressInterfaceFactory $addressFactory
  44. */
  45. public function __construct(
  46. CountryInformationAcquirerInterface $countryInformationAcquirer,
  47. CountryInformationInterfaceFactory $countryInformationFactory,
  48. ZipCodeFixer $zipCodeFixer,
  49. AddressInterfaceFactory $addressFactory
  50. ) {
  51. $this->countryInformationAcquirer = $countryInformationAcquirer;
  52. $this->countryInformationFactory = $countryInformationFactory;
  53. $this->zipCodeFixer = $zipCodeFixer;
  54. $this->addressFactory = $addressFactory;
  55. }
  56. /**
  57. * Build an {@see AddressInterface}
  58. *
  59. * @return AddressInterface
  60. */
  61. public function build()
  62. {
  63. $country = $this->getCountryInformation($this->countryCode);
  64. $companyState = $this->region ?: $this->getRegionCodeByCountryAndId($country, $this->regionId);
  65. $countryName = $country->getThreeLetterAbbreviation();
  66. /** @var AddressInterface $address */
  67. $address = $this->addressFactory->create();
  68. if (!empty($this->street)) {
  69. $address->setStreetAddress($this->street);
  70. }
  71. if (!empty($this->city)) {
  72. $address->setCity($this->city);
  73. }
  74. if ($companyState !== null) {
  75. $address->setMainDivision($companyState);
  76. }
  77. if (!empty($this->postalCode)) {
  78. $address->setPostalCode($this->zipCodeFixer->fix($this->postalCode));
  79. }
  80. if (!empty($countryName)) {
  81. $address->setCountry($countryName);
  82. }
  83. return $address;
  84. }
  85. /**
  86. * Set the City
  87. *
  88. * @param string $city
  89. * @return AddressBuilder
  90. */
  91. public function setCity($city)
  92. {
  93. $this->city = $city;
  94. return $this;
  95. }
  96. /**
  97. * Set the two-letter Country Code
  98. *
  99. * @param string $countryCode
  100. * @return AddressBuilder
  101. */
  102. public function setCountryCode($countryCode)
  103. {
  104. $this->countryCode = $countryCode;
  105. return $this;
  106. }
  107. /**
  108. * Set the Postal Code
  109. *
  110. * @param string $postalCode
  111. * @return AddressBuilder
  112. */
  113. public function setPostalCode($postalCode)
  114. {
  115. $this->postalCode = $postalCode;
  116. return $this;
  117. }
  118. /**
  119. * Set the Region string
  120. *
  121. * @param string $region
  122. * @return AddressBuilder
  123. */
  124. public function setRegion($region)
  125. {
  126. $this->region = $region;
  127. return $this;
  128. }
  129. /**
  130. * Set the Region ID
  131. *
  132. * @param string $regionId
  133. * @return AddressBuilder
  134. */
  135. public function setRegionId($regionId)
  136. {
  137. $this->regionId = $regionId;
  138. return $this;
  139. }
  140. /**
  141. * Set the Street Address
  142. *
  143. * @param string|string[] $rawStreet
  144. * @return AddressBuilder
  145. */
  146. public function setStreet($rawStreet)
  147. {
  148. if (!is_array($rawStreet)) {
  149. $rawStreet = [$rawStreet];
  150. }
  151. $street = [];
  152. foreach ($rawStreet as $rawLine) {
  153. if (!empty($rawLine)) {
  154. $street[] = $rawLine;
  155. }
  156. }
  157. $this->street = $street;
  158. return $this;
  159. }
  160. /**
  161. * Retrieve a country's information given its ID
  162. *
  163. * @param string $countryId Two letter country code
  164. * @return CountryInformationInterface
  165. */
  166. private function getCountryInformation($countryId)
  167. {
  168. try {
  169. return $this->countryInformationAcquirer->getCountryInfo($countryId);
  170. } catch (NoSuchEntityException $error) {
  171. return $this->countryInformationFactory->create();
  172. }
  173. }
  174. /**
  175. * Retrieve a region's code given its ID
  176. *
  177. * @param CountryInformationInterface $country
  178. * @param int $regionId
  179. *
  180. * @return string|null
  181. */
  182. private function getRegionCodeByCountryAndId(CountryInformationInterface $country, $regionId)
  183. {
  184. $regions = $country->getAvailableRegions();
  185. if ($regions === null) {
  186. return null;
  187. }
  188. // Linear search used since there exists no RegionInformationAcquirerInterface
  189. foreach ($regions as $region) {
  190. if ($region->getId() == $regionId) {
  191. return $region->getCode();
  192. }
  193. }
  194. return null;
  195. }
  196. }