PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/magento/module-tax/Model/Calculation/Rate.php

https://gitlab.com/daigiangaitu91/magento
PHP | 534 lines | 271 code | 53 blank | 210 comment | 28 complexity | fdb27450bc4eec601c38d9e89f345138 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. // @codingStandardsIgnoreFile
  7. namespace Magento\Tax\Model\Calculation;
  8. use Magento\Directory\Model\Region;
  9. use Magento\Framework\Api\AttributeValueFactory;
  10. use Magento\Framework\Exception\CouldNotDeleteException;
  11. use Magento\Tax\Api\Data\TaxRateInterface;
  12. /**
  13. * Tax Rate Model
  14. *
  15. * @method \Magento\Tax\Model\ResourceModel\Calculation\Rate _getResource()
  16. * @method \Magento\Tax\Model\ResourceModel\Calculation\Rate getResource()
  17. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  18. */
  19. class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements TaxRateInterface
  20. {
  21. /**#@+
  22. * Constants defined for keys of array, makes typos less likely
  23. */
  24. const KEY_ID = 'id';
  25. const KEY_COUNTRY_ID = 'tax_country_id';
  26. const KEY_REGION_ID = 'tax_region_id';
  27. const KEY_REGION_NAME = 'region_name';
  28. const KEY_POSTCODE = 'tax_postcode';
  29. const KEY_ZIP_IS_RANGE = 'zip_is_range';
  30. const KEY_ZIP_RANGE_FROM = 'zip_from';
  31. const KEY_ZIP_RANGE_TO = 'zip_to';
  32. const KEY_PERCENTAGE_RATE = 'rate';
  33. const KEY_CODE = 'code';
  34. const KEY_TITLES = 'titles';
  35. /**#@-*/
  36. /**
  37. * List of tax titles
  38. *
  39. * @var array
  40. */
  41. protected $_titles = null;
  42. /**
  43. * @var \Magento\Tax\Model\Calculation\Rate\Title
  44. */
  45. protected $_titleModel = null;
  46. /**
  47. * @var \Magento\Directory\Model\RegionFactory
  48. */
  49. protected $_regionFactory;
  50. /**
  51. * @var \Magento\Tax\Model\Calculation\Rate\TitleFactory
  52. */
  53. protected $_titleFactory;
  54. /**
  55. * @var Region
  56. */
  57. protected $directoryRegion;
  58. /**
  59. * @param \Magento\Framework\Model\Context $context
  60. * @param \Magento\Framework\Registry $registry
  61. * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
  62. * @param AttributeValueFactory $customAttributeFactory
  63. * @param \Magento\Directory\Model\RegionFactory $regionFactory
  64. * @param Rate\TitleFactory $taxTitleFactory
  65. * @param Region $directoryRegion
  66. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  67. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  68. * @param array $data
  69. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  70. */
  71. public function __construct(
  72. \Magento\Framework\Model\Context $context,
  73. \Magento\Framework\Registry $registry,
  74. \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
  75. AttributeValueFactory $customAttributeFactory,
  76. \Magento\Directory\Model\RegionFactory $regionFactory,
  77. \Magento\Tax\Model\Calculation\Rate\TitleFactory $taxTitleFactory,
  78. Region $directoryRegion,
  79. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  80. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  81. array $data = []
  82. ) {
  83. $this->_regionFactory = $regionFactory;
  84. $this->_titleFactory = $taxTitleFactory;
  85. $this->directoryRegion = $directoryRegion;
  86. parent::__construct(
  87. $context,
  88. $registry,
  89. $extensionFactory,
  90. $customAttributeFactory,
  91. $resource,
  92. $resourceCollection,
  93. $data
  94. );
  95. }
  96. /**
  97. * Magento model constructor
  98. *
  99. * @return void
  100. */
  101. protected function _construct()
  102. {
  103. $this->_init('Magento\Tax\Model\ResourceModel\Calculation\Rate');
  104. }
  105. /**
  106. * Prepare location settings and tax postcode before save rate
  107. *
  108. * @return \Magento\Tax\Model\Calculation\Rate
  109. * @throws \Magento\Framework\Exception\LocalizedException
  110. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  111. * @SuppressWarnings(PHPMD.NPathComplexity)
  112. */
  113. public function beforeSave()
  114. {
  115. $isWrongRange = $this->getZipIsRange() && ($this->getZipFrom() === '' || $this->getZipTo() === '');
  116. $isEmptyValues = $this->getCode() === '' ||
  117. $this->getTaxCountryId() === '' ||
  118. $this->getRate() === '' ||
  119. ($this->getTaxPostcode() === '' && !$this->getZipIsRange());
  120. if ($isEmptyValues || $isWrongRange) {
  121. throw new \Magento\Framework\Exception\LocalizedException(
  122. __('Make sure all required information is valid.')
  123. );
  124. }
  125. if (!is_numeric($this->getRate()) || $this->getRate() < 0) {
  126. throw new \Magento\Framework\Exception\LocalizedException(
  127. __('The Rate Percent should be a positive number.')
  128. );
  129. }
  130. if ($this->getZipIsRange()) {
  131. $zipFrom = $this->getZipFrom();
  132. $zipTo = $this->getZipTo();
  133. if (strlen($zipFrom) > 9 || strlen($zipTo) > 9) {
  134. throw new \Magento\Framework\Exception\LocalizedException(__('Maximum zip code length is 9.'));
  135. }
  136. if (!is_numeric($zipFrom) || !is_numeric($zipTo) || $zipFrom < 0 || $zipTo < 0) {
  137. throw new \Magento\Framework\Exception\LocalizedException(
  138. __('Use digits only for the zip code.')
  139. );
  140. }
  141. if ($zipFrom > $zipTo) {
  142. throw new \Magento\Framework\Exception\LocalizedException(
  143. __('Range To should be equal or greater than Range From.')
  144. );
  145. }
  146. $this->setTaxPostcode($zipFrom . '-' . $zipTo);
  147. } else {
  148. $taxPostCode = $this->getTaxPostcode();
  149. if (strlen($taxPostCode) > 10) {
  150. $taxPostCode = substr($taxPostCode, 0, 10);
  151. }
  152. $this->setTaxPostcode($taxPostCode)->setZipIsRange(null)->setZipFrom(null)->setZipTo(null);
  153. }
  154. parent::beforeSave();
  155. $country = $this->getTaxCountryId();
  156. $region = $this->getTaxRegionId();
  157. /** @var $regionModel \Magento\Directory\Model\Region */
  158. $regionModel = $this->_regionFactory->create();
  159. $regionModel->load($region);
  160. if ($regionModel->getCountryId() != $country) {
  161. $this->setTaxRegionId('*');
  162. }
  163. return $this;
  164. }
  165. /**
  166. * Save rate titles
  167. *
  168. * @return \Magento\Tax\Model\Calculation\Rate
  169. */
  170. public function afterSave()
  171. {
  172. $this->saveTitles();
  173. $this->_eventManager->dispatch('tax_settings_change_after');
  174. return parent::afterSave();
  175. }
  176. /**
  177. * Processing object before delete data
  178. *
  179. * @return \Magento\Tax\Model\Calculation\Rate
  180. * @throws \Magento\Framework\Exception\LocalizedException
  181. */
  182. public function beforeDelete()
  183. {
  184. if ($this->_isInRule()) {
  185. throw new CouldNotDeleteException(
  186. __('The tax rate cannot be removed. It exists in a tax rule.')
  187. );
  188. }
  189. return parent::beforeDelete();
  190. }
  191. /**
  192. * After rate delete
  193. * redeclared for dispatch tax_settings_change_after event
  194. *
  195. * @return \Magento\Tax\Model\Calculation\Rate
  196. */
  197. public function afterDelete()
  198. {
  199. $this->_eventManager->dispatch('tax_settings_change_after');
  200. return parent::afterDelete();
  201. }
  202. /**
  203. * Saves the tax titles
  204. *
  205. * @param array|null $titles
  206. * @return void
  207. */
  208. public function saveTitles($titles = null)
  209. {
  210. if (is_null($titles)) {
  211. $titles = $this->getTitle();
  212. }
  213. $this->getTitleModel()->deleteByRateId($this->getId());
  214. if (is_array($titles) && $titles) {
  215. foreach ($titles as $store => $title) {
  216. if ($title !== '') {
  217. $this->getTitleModel()->setId(
  218. null
  219. )->setTaxCalculationRateId(
  220. $this->getId()
  221. )->setStoreId(
  222. (int)$store
  223. )->setValue(
  224. $title
  225. )->save();
  226. }
  227. }
  228. }
  229. }
  230. /**
  231. * Returns a tax title
  232. *
  233. * @return \Magento\Tax\Model\Calculation\Rate\Title
  234. */
  235. public function getTitleModel()
  236. {
  237. if (is_null($this->_titleModel)) {
  238. $this->_titleModel = $this->_titleFactory->create();
  239. }
  240. return $this->_titleModel;
  241. }
  242. /**
  243. * {@inheritdoc}
  244. */
  245. public function getTitles()
  246. {
  247. if ($this->getData(self::KEY_TITLES)) {
  248. return $this->getData(self::KEY_TITLES);
  249. }
  250. if (is_null($this->_titles)) {
  251. $this->_titles = $this->getTitleModel()->getCollection()->loadByRateId($this->getId())->getItems();
  252. }
  253. return $this->_titles;
  254. }
  255. /**
  256. * Deletes all tax rates
  257. *
  258. * @return \Magento\Tax\Model\Calculation\Rate
  259. */
  260. public function deleteAllRates()
  261. {
  262. $this->_getResource()->deleteAllRates();
  263. $this->_eventManager->dispatch('tax_settings_change_after');
  264. return $this;
  265. }
  266. /**
  267. * Load rate model by code
  268. *
  269. * @param string $code
  270. * @return \Magento\Tax\Model\Calculation\Rate
  271. */
  272. public function loadByCode($code)
  273. {
  274. $this->load($code, 'code');
  275. return $this;
  276. }
  277. /**
  278. * Check if rate exists in tax rule
  279. *
  280. * @return array
  281. */
  282. protected function _isInRule()
  283. {
  284. return $this->getResource()->isInRule($this->getId());
  285. }
  286. /**
  287. * {@inheritdoc}
  288. */
  289. public function getRegionName()
  290. {
  291. if (!$this->getData(self::KEY_REGION_NAME)) {
  292. $regionName = $this->directoryRegion->load($this->getTaxRegionId())->getCode();
  293. $this->setData(self::KEY_REGION_NAME, $regionName);
  294. }
  295. return $this->getData(self::KEY_REGION_NAME);
  296. }
  297. /**
  298. * @codeCoverageIgnoreStart
  299. * {@inheritdoc}
  300. */
  301. public function getTaxCalculationRateId()
  302. {
  303. return $this->getData(self::KEY_ID);
  304. }
  305. /**
  306. * {@inheritdoc}
  307. */
  308. public function getTaxCountryId()
  309. {
  310. return $this->getData(self::KEY_COUNTRY_ID);
  311. }
  312. /**
  313. * {@inheritdoc}
  314. */
  315. public function getTaxRegionId()
  316. {
  317. return $this->getData(self::KEY_REGION_ID);
  318. }
  319. /**
  320. * {@inheritdoc}
  321. */
  322. public function getTaxPostcode()
  323. {
  324. return $this->getData(self::KEY_POSTCODE);
  325. }
  326. /**
  327. * {@inheritdoc}
  328. */
  329. public function getZipFrom()
  330. {
  331. return $this->getData(self::KEY_ZIP_RANGE_FROM);
  332. }
  333. /**
  334. * {@inheritdoc}
  335. */
  336. public function getZipTo()
  337. {
  338. return $this->getData(self::KEY_ZIP_RANGE_TO);
  339. }
  340. /**
  341. * {@inheritdoc}
  342. */
  343. public function getRate()
  344. {
  345. return $this->getData(self::KEY_PERCENTAGE_RATE);
  346. }
  347. /**
  348. * {@inheritdoc}
  349. */
  350. public function getCode()
  351. {
  352. return $this->getData(self::KEY_CODE);
  353. }
  354. /**
  355. * {@inheritdoc}
  356. */
  357. public function getZipIsRange()
  358. {
  359. return $this->getData(self::KEY_ZIP_IS_RANGE);
  360. }
  361. /**
  362. * Set country id
  363. *
  364. * @param string $taxCountryId
  365. * @return $this
  366. */
  367. public function setTaxCountryId($taxCountryId)
  368. {
  369. return $this->setData(self::KEY_COUNTRY_ID, $taxCountryId);
  370. }
  371. /**
  372. * Set region id
  373. *
  374. * @param int $taxRegionId
  375. * @return $this
  376. */
  377. public function setTaxRegionId($taxRegionId)
  378. {
  379. return $this->setData(self::KEY_REGION_ID, $taxRegionId);
  380. }
  381. /**
  382. * Set region name
  383. *
  384. * @param string $regionName
  385. * @return $this
  386. */
  387. public function setRegionName($regionName)
  388. {
  389. return $this->setData(self::KEY_REGION_NAME, $regionName);
  390. }
  391. /**
  392. * Set postcode
  393. *
  394. * @param string $taxPostCode
  395. * @return $this
  396. */
  397. public function setTaxPostcode($taxPostCode)
  398. {
  399. return $this->setData(self::KEY_POSTCODE, $taxPostCode);
  400. }
  401. /**
  402. * Set zip is range
  403. *
  404. * @param int $zipIsRange
  405. * @return $this
  406. */
  407. public function setZipIsRange($zipIsRange)
  408. {
  409. return $this->setData(self::KEY_ZIP_IS_RANGE, $zipIsRange);
  410. }
  411. /**
  412. * Set zip range from
  413. *
  414. * @param int $zipFrom
  415. * @return $this
  416. */
  417. public function setZipFrom($zipFrom)
  418. {
  419. return $this->setData(self::KEY_ZIP_RANGE_FROM, $zipFrom);
  420. }
  421. /**
  422. * Set zip range to
  423. *
  424. * @param int $zipTo
  425. * @return $this
  426. */
  427. public function setZipTo($zipTo)
  428. {
  429. return $this->setData(self::KEY_ZIP_RANGE_TO, $zipTo);
  430. }
  431. /**
  432. * Set tax rate in percentage
  433. *
  434. * @param float $rate
  435. * @return $this
  436. */
  437. public function setRate($rate)
  438. {
  439. return $this->setData(self::KEY_PERCENTAGE_RATE, $rate);
  440. }
  441. /**
  442. * Set tax rate code
  443. *
  444. * @param string $code
  445. * @return $this
  446. */
  447. public function setCode($code)
  448. {
  449. return $this->setData(self::KEY_CODE, $code);
  450. }
  451. /**
  452. * Set tax rate titles
  453. *
  454. * @param \Magento\Tax\Api\Data\TaxRateTitleInterface[] $titles
  455. * @return $this
  456. */
  457. public function setTitles(array $titles = null)
  458. {
  459. return $this->setData(self::KEY_TITLES, $titles);
  460. }
  461. // @codeCoverageIgnoreEnd
  462. /**
  463. * {@inheritdoc}
  464. *
  465. * @return \Magento\Tax\Api\Data\TaxRateExtensionInterface|null
  466. */
  467. public function getExtensionAttributes()
  468. {
  469. return $this->_getExtensionAttributes();
  470. }
  471. /**
  472. * {@inheritdoc}
  473. *
  474. * @param \Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes
  475. * @return $this
  476. */
  477. public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes)
  478. {
  479. return $this->_setExtensionAttributes($extensionAttributes);
  480. }
  481. }