Agreement.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Paypal\Model\Billing;
  7. use Magento\Sales\Model\Order\Payment;
  8. /**
  9. * Billing Agreement abstract model
  10. *
  11. * @api
  12. * @method int getCustomerId()
  13. * @method \Magento\Paypal\Model\Billing\Agreement setCustomerId(int $value)
  14. * @method string getMethodCode()
  15. * @method \Magento\Paypal\Model\Billing\Agreement setMethodCode(string $value)
  16. * @method string getReferenceId()
  17. * @method \Magento\Paypal\Model\Billing\Agreement setReferenceId(string $value)
  18. * @method string getStatus()
  19. * @method \Magento\Paypal\Model\Billing\Agreement setStatus(string $value)
  20. * @method string getCreatedAt()
  21. * @method \Magento\Paypal\Model\Billing\Agreement setCreatedAt(string $value)
  22. * @method string getUpdatedAt()
  23. * @method \Magento\Paypal\Model\Billing\Agreement setUpdatedAt(string $value)
  24. * @method int getStoreId()
  25. * @method \Magento\Paypal\Model\Billing\Agreement setStoreId(int $value)
  26. * @method string getAgreementLabel()
  27. * @method \Magento\Paypal\Model\Billing\Agreement setAgreementLabel(string $value)
  28. *
  29. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  30. * @since 100.0.2
  31. */
  32. class Agreement extends \Magento\Paypal\Model\Billing\AbstractAgreement
  33. {
  34. const STATUS_ACTIVE = 'active';
  35. const STATUS_CANCELED = 'canceled';
  36. /**
  37. * Related agreement orders
  38. *
  39. * @var array
  40. */
  41. protected $_relatedOrders = [];
  42. /**
  43. * @var \Magento\Paypal\Model\ResourceModel\Billing\Agreement\CollectionFactory
  44. */
  45. protected $_billingAgreementFactory;
  46. /**
  47. * @var \Magento\Framework\Stdlib\DateTime\DateTimeFactory
  48. */
  49. protected $_dateFactory;
  50. /**
  51. * @param \Magento\Framework\Model\Context $context
  52. * @param \Magento\Framework\Registry $registry
  53. * @param \Magento\Payment\Helper\Data $paymentData
  54. * @param \Magento\Paypal\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementFactory
  55. * @param \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory
  56. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  57. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  58. * @param array $data
  59. */
  60. public function __construct(
  61. \Magento\Framework\Model\Context $context,
  62. \Magento\Framework\Registry $registry,
  63. \Magento\Payment\Helper\Data $paymentData,
  64. \Magento\Paypal\Model\ResourceModel\Billing\Agreement\CollectionFactory $billingAgreementFactory,
  65. \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
  66. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  67. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  68. array $data = []
  69. ) {
  70. parent::__construct($context, $registry, $paymentData, $resource, $resourceCollection, $data);
  71. $this->_billingAgreementFactory = $billingAgreementFactory;
  72. $this->_dateFactory = $dateFactory;
  73. }
  74. /**
  75. * Init model
  76. *
  77. * @return void
  78. */
  79. protected function _construct()
  80. {
  81. $this->_init(\Magento\Paypal\Model\ResourceModel\Billing\Agreement::class);
  82. }
  83. /**
  84. * Set created_at parameter
  85. *
  86. * @return \Magento\Framework\Model\AbstractModel
  87. */
  88. public function beforeSave()
  89. {
  90. $date = $this->_dateFactory->create()->gmtDate();
  91. if ($this->isObjectNew() && !$this->getCreatedAt()) {
  92. $this->setCreatedAt($date);
  93. } else {
  94. $this->setUpdatedAt($date);
  95. }
  96. return parent::beforeSave();
  97. }
  98. /**
  99. * Save agreement order relations
  100. *
  101. * @return \Magento\Framework\Model\AbstractModel
  102. */
  103. public function afterSave()
  104. {
  105. if (!empty($this->_relatedOrders)) {
  106. $this->_saveOrderRelations();
  107. }
  108. return parent::afterSave();
  109. }
  110. /**
  111. * Retrieve billing agreement status label
  112. *
  113. * @return \Magento\Framework\Phrase|string
  114. */
  115. public function getStatusLabel()
  116. {
  117. switch ($this->getStatus()) {
  118. case self::STATUS_ACTIVE:
  119. return __('Active');
  120. case self::STATUS_CANCELED:
  121. return __('Canceled');
  122. default:
  123. return '';
  124. }
  125. }
  126. /**
  127. * Initialize token
  128. *
  129. * @return string
  130. */
  131. public function initToken()
  132. {
  133. $this->getPaymentMethodInstance()
  134. ->initBillingAgreementToken($this);
  135. return $this->getRedirectUrl();
  136. }
  137. /**
  138. * Get billing agreement details
  139. * Data from response is inside this object
  140. *
  141. * @return $this
  142. */
  143. public function verifyToken()
  144. {
  145. $this->getPaymentMethodInstance()
  146. ->getBillingAgreementTokenInfo($this);
  147. return $this;
  148. }
  149. /**
  150. * Create billing agreement
  151. *
  152. * @return $this
  153. */
  154. public function place()
  155. {
  156. $this->verifyToken();
  157. $paymentMethodInstance = $this->getPaymentMethodInstance();
  158. $paymentMethodInstance->placeBillingAgreement($this);
  159. $this->setCustomerId($this->getCustomerId())
  160. ->setMethodCode($this->getMethodCode())
  161. ->setReferenceId($this->getBillingAgreementId())
  162. ->setStatus(self::STATUS_ACTIVE)
  163. ->setAgreementLabel($paymentMethodInstance->getTitle())
  164. ->save();
  165. return $this;
  166. }
  167. /**
  168. * Cancel billing agreement
  169. *
  170. * @return $this
  171. */
  172. public function cancel()
  173. {
  174. $this->setStatus(self::STATUS_CANCELED);
  175. $this->getPaymentMethodInstance()->updateBillingAgreementStatus($this);
  176. return $this->save();
  177. }
  178. /**
  179. * Check whether can cancel billing agreement
  180. *
  181. * @return bool
  182. */
  183. public function canCancel()
  184. {
  185. return $this->getStatus() != self::STATUS_CANCELED;
  186. }
  187. /**
  188. * Retrieve billing agreement statuses array
  189. *
  190. * @return array
  191. */
  192. public function getStatusesArray()
  193. {
  194. return [
  195. self::STATUS_ACTIVE => __('Active'),
  196. self::STATUS_CANCELED => __('Canceled')
  197. ];
  198. }
  199. /**
  200. * Validate data
  201. *
  202. * @return bool
  203. */
  204. public function isValid()
  205. {
  206. $result = parent::isValid();
  207. if (!$this->getCustomerId()) {
  208. $this->_errors[] = __('The customer ID is not set.');
  209. }
  210. if (!$this->getStatus()) {
  211. $this->_errors[] = __('The Billing Agreement status is not set.');
  212. }
  213. return $result && empty($this->_errors);
  214. }
  215. /**
  216. * Import payment data to billing agreement
  217. *
  218. * $payment->getBillingAgreementData() contains array with following structure :
  219. * [billing_agreement_id] => string
  220. * [method_code] => string
  221. *
  222. * @param Payment $payment
  223. * @return $this
  224. */
  225. public function importOrderPayment(Payment $payment)
  226. {
  227. $baData = $payment->getBillingAgreementData();
  228. $this->_paymentMethodInstance = (isset($baData['method_code']))
  229. ? $this->_paymentData->getMethodInstance($baData['method_code'])
  230. : $payment->getMethodInstance();
  231. $this->_paymentMethodInstance->setStore($payment->getMethodInstance()->getStore());
  232. $this->setCustomerId($payment->getOrder()->getCustomerId())
  233. ->setMethodCode($this->_paymentMethodInstance->getCode())
  234. ->setReferenceId($baData['billing_agreement_id'])
  235. ->setStatus(self::STATUS_ACTIVE)
  236. ->setAgreementLabel($this->_paymentMethodInstance->getTitle());
  237. return $this;
  238. }
  239. /**
  240. * Retrieve available customer Billing Agreements
  241. *
  242. * @param int $customerId
  243. * @return \Magento\Paypal\Model\ResourceModel\Billing\Agreement\Collection
  244. */
  245. public function getAvailableCustomerBillingAgreements($customerId)
  246. {
  247. $collection = $this->_billingAgreementFactory->create();
  248. $collection->addFieldToFilter('customer_id', $customerId)
  249. ->addFieldToFilter('status', self::STATUS_ACTIVE)
  250. ->setOrder('agreement_id');
  251. return $collection;
  252. }
  253. /**
  254. * Check whether need to create billing agreement for customer
  255. *
  256. * @param int $customerId
  257. * @return bool
  258. */
  259. public function needToCreateForCustomer($customerId)
  260. {
  261. return $customerId ? count($this->getAvailableCustomerBillingAgreements($customerId)) == 0 : false;
  262. }
  263. /**
  264. * Add order relation to current billing agreement
  265. *
  266. * @param int|\Magento\Sales\Model\Order $orderId
  267. * @return $this
  268. */
  269. public function addOrderRelation($orderId)
  270. {
  271. $this->_relatedOrders[] = $orderId;
  272. return $this;
  273. }
  274. /**
  275. * Save related orders
  276. *
  277. * @return void
  278. */
  279. protected function _saveOrderRelations()
  280. {
  281. foreach ($this->_relatedOrders as $order) {
  282. $orderId = $order instanceof \Magento\Sales\Model\Order ? $order->getId() : (int)$order;
  283. $this->getResource()->addOrderRelation($this->getId(), $orderId);
  284. }
  285. }
  286. }