BxPaymentSubscriptions.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup Payment Payment
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxPaymentSubscriptions extends BxBaseModPaymentSubscriptions
  12. {
  13. function __construct()
  14. {
  15. $this->MODULE = 'bx_payment';
  16. parent::__construct();
  17. }
  18. /*
  19. * Service methods
  20. */
  21. /**
  22. * @page service Service Calls
  23. * @section bx_payment Payment
  24. * @subsection bx_payment-page_blocks Page Blocks
  25. * @subsubsection bx_payment-get_block_list_my get_block_list_my
  26. *
  27. * @code bx_srv('bx_payment', 'get_block_list_my', [...], 'Subscriptions'); @endcode
  28. *
  29. * Get page block with a list of currently logged in member's subscriptions.
  30. *
  31. * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  32. *
  33. * @see BxPaymentSubscriptions::serviceGetBlockListMy
  34. */
  35. /**
  36. * @ref bx_payment-get_block_list_my "get_block_list_my"
  37. */
  38. public function serviceGetBlockListMy()
  39. {
  40. return $this->_getBlock('list_my');
  41. }
  42. /**
  43. * @page service Service Calls
  44. * @section bx_payment Payment
  45. * @subsection bx_payment-page_blocks Page Blocks
  46. * @subsubsection bx_payment-get_block_list_all get_block_list_all
  47. *
  48. * @code bx_srv('bx_payment', 'get_block_list_all', [...], 'Subscriptions'); @endcode
  49. *
  50. * Get page block with a list of all subscriptions. It's available for authorized members only.
  51. *
  52. * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  53. *
  54. * @see BxPaymentSubscriptions::serviceGetBlockListAll
  55. */
  56. /**
  57. * @ref bx_payment-get_block_list_all "get_block_list_all"
  58. */
  59. public function serviceGetBlockListAll()
  60. {
  61. return $this->_getBlock('list_all');
  62. }
  63. /**
  64. * @page service Service Calls
  65. * @section bx_payment Payment
  66. * @subsection bx_payment-page_blocks Page Blocks
  67. * @subsubsection bx_payment-get_block_history get_block_history
  68. *
  69. * @code bx_srv('bx_payment', 'get_block_history', [...], 'Subscriptions'); @endcode
  70. *
  71. * Get page block with a list of payments related to subscriptions of currently logged in member.
  72. *
  73. * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  74. *
  75. * @see BxPaymentSubscriptions::serviceGetBlockHistory
  76. */
  77. /**
  78. * @ref bx_payment-get_block_history "get_block_history"
  79. */
  80. public function serviceGetBlockHistory()
  81. {
  82. return $this->_getBlock('history');
  83. }
  84. /**
  85. * @page service Service Calls
  86. * @section bx_payment Payment
  87. * @subsection bx_payment-other Other
  88. * @subsubsection bx_payment-get_subscription_orders_info get_subscription_orders_info
  89. *
  90. * @code bx_srv('bx_payment', 'get_subscription_orders_info', [...], 'Subscriptions'); @endcode
  91. *
  92. * Get subscription transaction(s) which meets all requirements.
  93. *
  94. * @param $aConditions an array of pears('key' => 'value'). The most useful keys are the following:
  95. * a. client_id - client's ID (integer)
  96. * b. seller_id - seller's ID (integer)
  97. * c. type - transaction type: single or recurring (string)
  98. * d. amount - transaction amount (float)
  99. * e. order - order ID received from payment provider (string)
  100. * f. provider - payment provider name (string)
  101. * g. date - the date when the payment was established(UNIXTIME STAMP)
  102. * h. processed - whether the payment was processed or not (integer, 0 or 1)
  103. * @return an array of transactions. Each transaction has full info(client ID, seller ID, external transaction ID, date and so on)
  104. *
  105. * @see BxPaymentSubscriptions::serviceGetSubscriptionOrdersInfo
  106. */
  107. /**
  108. * @ref bx_payment-get_subscription_orders_info "get_subscription_orders_info"
  109. */
  110. public function serviceGetSubscriptionOrdersInfo($aConditions)
  111. {
  112. if(empty($aConditions) || !is_array($aConditions))
  113. return array();
  114. return $this->_oModule->_oDb->getOrderSubscription(array('type' => 'mixed', 'conditions' => $aConditions));
  115. }
  116. /**
  117. * @page service Service Calls
  118. * @section bx_payment Payment
  119. * @subsection bx_payment-other Other
  120. * @subsubsection bx_payment-get_subscriptions_info get_subscriptions_info
  121. *
  122. * @code bx_srv('bx_payment', 'get_subscriptions_info', [...], 'Subscriptions'); @endcode
  123. *
  124. * Get subscription(s) which meets all requirements.
  125. *
  126. * @param $aConditions an array of pears('key' => 'value'). The most useful keys are the following:
  127. * a. pending_id - pending transaction ID (integer)
  128. * b. customer_id - customer ID from payment provider (string)
  129. * c. subscription_id - subscription ID from payment provider (string)
  130. * d. paid - flag determining whether the subscription paid or not (integer)
  131. * e. date - the date when the subscription was established(UNIXTIME STAMP)
  132. * @param $bCheckInProvider boolean value determining whether the subscription should be checked in associated payment provider.
  133. * @return an array of subscriptions. Each subscription has full info(pending ID, customer ID, subscription ID and so on)
  134. *
  135. * @see BxPaymentSubscriptions::serviceGetSubscriptionsInfo
  136. */
  137. /**
  138. * @ref bx_payment-get_subscriptions_info "get_subscriptions_info"
  139. */
  140. public function serviceGetSubscriptionsInfo($aConditions, $bCheckInProvider = false)
  141. {
  142. if(empty($aConditions) || !is_array($aConditions))
  143. return array();
  144. $aSubscriptions = $this->_oModule->_oDb->getSubscription(array('type' => 'mixed_ext', 'conditions' => $aConditions));
  145. if(empty($aSubscriptions) || !is_array($aSubscriptions) || !$bCheckInProvider)
  146. return $aSubscriptions;
  147. foreach($aSubscriptions as $iKey => $aSubscription) {
  148. if(empty($aSubscription['provider']) || $aSubscription['provider'] == 'manual')
  149. continue;
  150. $oProvider = $this->_oModule->getObjectProvider($aSubscription['provider'], $aSubscription['seller_id']);
  151. if(!$oProvider)
  152. continue;
  153. $aSubscriptions[$iKey]['data'] = $oProvider->getSubscription($aSubscription['pending_id'], $aSubscription['customer_id'], $aSubscription['subscription_id']);
  154. }
  155. return $aSubscriptions;
  156. }
  157. /**
  158. * @page service Service Calls
  159. * @section bx_payment Payment
  160. * @subsection bx_payment-other Other
  161. * @subsubsection bx_payment-get_subscriptions_after get_subscriptions_after
  162. *
  163. * @code bx_srv('bx_payment', 'get_subscriptions_after', [0, 500, false], 'Subscriptions'); @endcode
  164. *
  165. * Get subscriptions a page at a time, ordered by their pending transaction ID, to read
  166. * them all in steps. Pass the pending ID of the last subscription of the previous page to
  167. * get the next one.
  168. *
  169. * @param $iAfterPendingId integer value, the subscriptions with a greater pending ID are returned (0 for the first page).
  170. * @param $iLimit integer value, subscriptions per page (at most 5000).
  171. * @param $bDeleted boolean value, read cancelled (deleted) subscriptions instead of the current ones.
  172. * @return an array of subscriptions. Each has pending_id, subscription_id, period, period_unit, trial, date_add, date_next and status, its order's client_id, seller_id, type, provider, items, amount, currency, order and data, and for deleted ones the reason and the time they were deleted.
  173. *
  174. * @see BxPaymentSubscriptions::serviceGetSubscriptionsAfter
  175. */
  176. /**
  177. * @ref bx_payment-get_subscriptions_after "get_subscriptions_after"
  178. */
  179. public function serviceGetSubscriptionsAfter($iAfterPendingId = 0, $iLimit = 500, $bDeleted = false)
  180. {
  181. return $this->_oModule->_oDb->getSubscriptionsAfter((int)$iAfterPendingId, (int)$iLimit, (bool)$bDeleted);
  182. }
  183. /**
  184. * @page service Service Calls
  185. * @section bx_payment Payment
  186. * @subsection bx_payment-purchase_processing Purchase Processing
  187. * @subsubsection bx_payment-subscribe subscribe
  188. *
  189. * @code bx_srv('bx_payment', 'subscribe', [...], 'Subscriptions'); @endcode
  190. *
  191. * Initialize subscription for specified item.
  192. *
  193. * @param $iSellerId integer value with seller ID.
  194. * @param $sSellerProvider string value with a name of payment provider to be used for processing. Empty value means that payment provider selector should be shown.
  195. * @param $iModuleId integer value with module ID.
  196. * @param $iItemId integer value with item ID.
  197. * @param $iItemCount integer value with a number of items for purchasing. It's equal to 1 in case of subscription.
  198. * @param $sRedirect (optional) string value with redirect URL, if it's needed.
  199. * @return an array with special format which describes the result of operation.
  200. *
  201. * @see BxPaymentSubscriptions::serviceSubscribe
  202. */
  203. /**
  204. * @ref bx_payment-subscribe "subscribe"
  205. */
  206. public function serviceSubscribe($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, $sRedirect = '', $aCustom = array())
  207. {
  208. return $this->serviceSubscribeWithAddons($iSellerId, $sSellerProvider, $iModuleId, $iItemId, $iItemCount, '', $sRedirect, $aCustom);
  209. }
  210. /**
  211. * @page service Service Calls
  212. * @section bx_payment Payment
  213. * @subsection bx_payment-purchase_processing Purchase Processing
  214. * @subsubsection bx_payment-subscribe_with_addons subscribe_with_addons
  215. *
  216. * @code bx_srv('bx_payment', 'subscribe_with_addons', [...], 'Subscriptions'); @endcode
  217. *
  218. * Initialize subscription for specified item.
  219. *
  220. * @param $iSellerId integer value with seller ID.
  221. * @param $sSellerProvider string value with a name of payment provider to be used for processing. Empty value means that payment provider selector should be shown.
  222. * @param $iModuleId integer value with module ID.
  223. * @param $iItemId integer value with item ID.
  224. * @param $iItemCount integer value with a number of items for purchasing. It's equal to 1 in case of subscription.
  225. * @param $sItemAddons (optional) string with attached addons.
  226. * @param $sRedirect (optional) string value with redirect URL, if it's needed.
  227. * @return an array with special format which describes the result of operation.
  228. *
  229. * @see BxPaymentSubscriptions::serviceSubscribeWithAddons
  230. */
  231. /**
  232. * @ref bx_payment-subscribe_with_addons "subscribe_with_addons"
  233. */
  234. public function serviceSubscribeWithAddons($iSellerId, $sSellerProvider, $mixedModuleId, $iItemId, $iItemCount, $sItemAddons = '', $sRedirect = '', $aCustom = array())
  235. {
  236. $CNF = &$this->_oModule->_oConfig->CNF;
  237. $iModuleId = $this->_oModule->_oConfig->getModuleId($mixedModuleId);
  238. $iClientId = $this->_oModule->getProfileId();
  239. $mixedResult = $this->_oModule->checkData($iClientId, $iSellerId, $iModuleId, $iItemId, $iItemCount);
  240. if($mixedResult !== true)
  241. return $mixedResult;
  242. $aSellerProviders = $this->_oModule->_oDb->getVendorInfoProvidersRecurring($iSellerId, true);
  243. if(empty($aSellerProviders))
  244. return array('code' => 5, 'message' => _t($CNF['T']['ERR_NOT_ACCEPT_PAYMENTS']));
  245. $aCartItem = array($iSellerId, $iModuleId, $iItemId, $iItemCount, $sItemAddons);
  246. if(empty($sSellerProvider)) {
  247. $sId = $this->_oModule->_oConfig->getHtmlIds('cart', 'providers_select') . BX_PAYMENT_TYPE_RECURRING;
  248. $sTitle = _t($CNF['T']['POPUP_PROVIDERS_SELECT']);
  249. return array('popup' => array(
  250. 'html' => BxTemplFunctions::getInstance()->popupBox($sId, $sTitle, $this->_oModule->_oTemplate->displayProvidersSelector($aCartItem, $aSellerProviders, $sRedirect, $aCustom)),
  251. 'options' => array('closeOnOuterClick' => true)
  252. ));
  253. }
  254. $aCustoms = array();
  255. $this->_oModule->_oConfig->putCustom($aCartItem, $aCustom, $aCustoms);
  256. $sCartItem = $this->_oModule->_oConfig->descriptorA2S($aCartItem);
  257. $mixedResult = $this->_oModule->serviceInitializeCheckout(BX_PAYMENT_TYPE_RECURRING, $iSellerId, $aSellerProviders[$sSellerProvider]['name'], array($sCartItem), $sRedirect, $aCustoms);
  258. if(is_string($mixedResult))
  259. return array('code' => 6, 'message' => _t($mixedResult));
  260. return $mixedResult;
  261. }
  262. public function serviceCancel($sOrder, $bForce = true)
  263. {
  264. $aPending = $this->_oModule->_oDb->getOrderPending(['type' => 'order', 'order' => $sOrder]);
  265. if(empty($aPending) || !is_array($aPending))
  266. return ['code' => 1, 'message' => _t('_bx_payment_err_not_found_pending')];
  267. if(!(bool)$bForce && ($mixedResult = $this->_oModule->isAllowedManage($aPending)) !== true)
  268. return ['code' => 2, 'message' => $mixedResult];
  269. if(!$this->cancel((int)$aPending['id']))
  270. return ['code' => 3, 'message' => _t('_bx_payment_err_cannot_perform')];
  271. return ['code' => 0, 'message' => _t('_bx_payment_msg_successfully_performed')];
  272. }
  273. public function serviceCancelByPendingId($iId, $bForce = true)
  274. {
  275. $aPending = $this->_oModule->_oDb->getOrderPending(['type' => 'id', 'id' => $iId]);
  276. if(empty($aPending) || !is_array($aPending))
  277. return ['code' => 1, 'message' => _t('_bx_payment_err_not_found_pending')];
  278. if(!(bool)$bForce && ($mixedResult = $this->_oModule->isAllowedManage($aPending)) !== true)
  279. return ['code' => 2, 'message' => $mixedResult];
  280. if(!$this->cancel((int)$aPending['id']))
  281. return ['code' => 3, 'message' => _t('_bx_payment_err_cannot_perform')];
  282. return ['code' => 0, 'message' => _t('_bx_payment_msg_successfully_performed')];
  283. }
  284. /**
  285. * @page service Service Calls
  286. * @section bx_payment Payment
  287. * @subsection bx_payment-purchase_processing Purchase Processing
  288. * @subsubsection bx_payment-send_subscription_expiration_letters send_subscription_expiration_letters
  289. *
  290. * @code bx_srv('bx_payment', 'send_subscription_expiration_letters', [...], 'Subscriptions'); @endcode
  291. *
  292. * Send subscription expiration letters.
  293. *
  294. * @param $iPendingId integer value with pending transaction ID.
  295. * @param $sOrderId string value with order ID.
  296. *
  297. * @see BxPaymentSubscriptions::serviceSendSubscriptionExpirationLetters
  298. */
  299. /**
  300. * @ref bx_payment-send_subscription_expiration_letters "send_subscription_expiration_letters"
  301. */
  302. public function serviceSendSubscriptionExpirationLetters($iPendingId, $sOrderId)
  303. {
  304. $CNF = &$this->_oModule->_oConfig->CNF;
  305. $sPrefix = $this->_oModule->_oConfig->getPrefix('general');
  306. $aSubscription = $this->serviceGetSubscriptionsInfo(array('subscription_id' => $sOrderId));
  307. if(empty($aSubscription) || !is_array($aSubscription))
  308. return;
  309. $aSubscription = array_shift($aSubscription);
  310. $oSeller = BxDolProfile::getInstance((int)$aSubscription['seller_id']);
  311. $oClient = BxDolProfile::getInstance((int)$aSubscription['client_id']);
  312. $aEtParams = array(
  313. 'subscription_id' => $aSubscription['subscription_id'],
  314. 'subscription_customer' => $aSubscription['customer_id'],
  315. 'subscription_date' => bx_time_js($aSubscription['date_add'], BX_FORMAT_DATE, true)
  316. );
  317. /**
  318. * Notify seller.
  319. */
  320. if($oSeller !== false) {
  321. $sEmail = '';
  322. $oProvider = $this->_oModule->getObjectProvider($aSubscription['provider'], $aSubscription['seller_id']);
  323. if($oProvider !== false && $oProvider->isActive())
  324. $sEmail = $oProvider->getOption('expiration_email');
  325. if(empty($sEmail))
  326. $sEmail = $oSeller->getAccountObject()->getEmail();
  327. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($sPrefix . 'expiration_notification_seller', $aEtParams, 0, (int)$aSubscription['client_id']);
  328. sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM);
  329. }
  330. /**
  331. * Notify client.
  332. */
  333. if($oClient !== false) {
  334. $sEmail = $oClient->getAccountObject()->getEmail();
  335. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($sPrefix . 'expiration_notification_client', $aEtParams, 0, (int)$aSubscription['seller_id']);
  336. sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM);
  337. }
  338. }
  339. public function register($aPending, $aParams = array())
  340. {
  341. if($this->_oModule->_oDb->isSubscriptionByPending($aPending['id']) || empty($aPending['items']))
  342. return false;
  343. $aInfo = $this->_oModule->getObjectCart()->getInfo(BX_PAYMENT_TYPE_RECURRING, $aPending['client_id'], $aPending['seller_id'], $aPending['items']);
  344. if(empty($aInfo['items']) || !is_array($aInfo['items']))
  345. return false;
  346. $aItem = array_shift($aInfo['items']);
  347. $iPeriod = (int)$aItem['period_recurring'];
  348. $iTrial = (int)$aItem['trial_recurring'];
  349. $oDate = date_create();
  350. $iNow = $iNext = date_format($oDate, 'U');
  351. if((!empty($aParams['status']) && $aParams['status'] == BX_PAYMENT_SBS_STATUS_ACTIVE) || $iTrial > 0) {
  352. $sInterval = $this->_getInterval($iPeriod, $aItem['period_unit_recurring'], $iTrial);
  353. date_add($oDate, new DateInterval($sInterval));
  354. $iNext = date_format($oDate, 'U');
  355. }
  356. $sUnique = genRndPwd(9, false);
  357. $aSubscription = array(
  358. 'pending_id' => $aPending['id'],
  359. 'customer_id' => !empty($aParams['customer_id']) ? $aParams['customer_id'] : 'bx_cus_' . $sUnique,
  360. 'subscription_id' => !empty($aParams['subscription_id']) ? $aParams['subscription_id'] : 'bx_sub_' . $sUnique,
  361. 'period' => $iPeriod,
  362. 'period_unit' => $aItem['period_unit_recurring'],
  363. 'trial' => $iTrial,
  364. 'date_add' => $iNow,
  365. 'date_next' => $iNext,
  366. 'status' => !empty($aParams['status']) ? $aParams['status'] : ($iTrial > 0 ? BX_PAYMENT_SBS_STATUS_TRIAL : BX_PAYMENT_SBS_STATUS_UNPAID)
  367. );
  368. if(!$this->_oModule->_oDb->insertSubscription($aSubscription))
  369. return false;
  370. $this->_oModule->onSubscriptionCreate($aPending, $aSubscription);
  371. return true;
  372. }
  373. public function prolong($aPending, $aParams = array())
  374. {
  375. if(empty($aPending['items']))
  376. return false;
  377. $aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $aPending['id']));
  378. if(empty($aSubscription) || !is_array($aSubscription))
  379. return false;
  380. $aInfo = $this->_oModule->getObjectCart()->getInfo(BX_PAYMENT_TYPE_RECURRING, $aPending['client_id'], $aPending['seller_id'], $aPending['items']);
  381. if(empty($aInfo['items']) || !is_array($aInfo['items']))
  382. return false;
  383. $aItem = array_shift($aInfo['items']);
  384. $iItemPeriod = (int)$aItem['period_recurring'];
  385. $sItemPeriodUnit = $aItem['period_unit_recurring'];
  386. $iDateNext = 0;
  387. if(!empty($iItemPeriod) && !empty($sItemPeriodUnit)) {
  388. $sInterval = $this->_getInterval($iItemPeriod, $sItemPeriodUnit);
  389. if(empty($sInterval))
  390. return false;
  391. $oDate = date_create('@' . $aSubscription['date_next']);
  392. date_add($oDate, new DateInterval($sInterval));
  393. $iDateNext = date_format($oDate, 'U');
  394. }
  395. $this->_oModule->_oDb->updateSubscription(array_merge(array(
  396. 'date_next' => $iDateNext,
  397. 'pay_attempts' => 0,
  398. 'status' => BX_PAYMENT_SBS_STATUS_ACTIVE
  399. ), $aParams), array(
  400. 'id' => $aSubscription['id']
  401. ));
  402. $this->_oModule->onSubscriptionProlong($aPending, $aSubscription);
  403. return true;
  404. }
  405. public function overdue($aPending, $aParams = array())
  406. {
  407. $aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $aPending['id']));
  408. if(empty($aSubscription) || !is_array($aSubscription))
  409. return false;
  410. $this->_oModule->_oDb->updateSubscription(array_merge(array(
  411. 'status' => BX_PAYMENT_SBS_STATUS_UNPAID
  412. ), $aParams), array(
  413. 'id' => $aSubscription['id']
  414. ));
  415. $this->_oModule->onSubscriptionOverdue($aPending, $aSubscription);
  416. return true;
  417. }
  418. public function cancel($iPendingId, $sReason = '')
  419. {
  420. if(!$this->cancelRemote($iPendingId))
  421. return false;
  422. if(!$this->cancelLocal($iPendingId, $sReason))
  423. return false;
  424. return true;
  425. }
  426. public function cancelRemote($mixedPending)
  427. {
  428. $aPending = is_array($mixedPending) ? $mixedPending : $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$mixedPending));
  429. if(empty($aPending) || !is_array($aPending) || $aPending['type'] != BX_PAYMENT_TYPE_RECURRING)
  430. return false;
  431. $aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $aPending['id']));
  432. if(empty($aSubscription) || !is_array($aSubscription))
  433. return false;
  434. $iSellerId = (int)$aPending['seller_id'];
  435. $oProvider = $this->_oModule->getObjectProvider($aPending['provider'], $iSellerId);
  436. if($oProvider === false || !$oProvider->isActive())
  437. return false;
  438. if(!$oProvider->cancelRecurring($aPending['id'], $aSubscription['customer_id'], $aSubscription['subscription_id']))
  439. return false;
  440. return true;
  441. }
  442. public function cancelLocal($mixedPending, $sReason = 'cancel')
  443. {
  444. $aPending = is_array($mixedPending) ? $mixedPending : $this->_oModule->_oDb->getOrderPending(array('type' => 'id', 'id' => (int)$mixedPending));
  445. if(empty($aPending) || !is_array($aPending) || $aPending['type'] != BX_PAYMENT_TYPE_RECURRING)
  446. return false;
  447. $aSubscription = $this->_oModule->_oDb->getSubscription(array('type' => 'pending_id', 'pending_id' => $aPending['id']));
  448. if(empty($aSubscription) || !is_array($aSubscription))
  449. return false;
  450. $aItems = $this->_oModule->_oConfig->descriptorsM2A($aPending['items']);
  451. foreach($aItems as $aItem)
  452. $this->_oModule->callCancelSubscriptionItem((int)$aItem['module_id'], array($aPending['client_id'], $aPending['seller_id'], $aItem['item_id'], $aItem['item_count'], $aPending['order']));
  453. if(!$this->_oModule->_oDb->deleteSubscription($aSubscription['id'], $sReason))
  454. return false;
  455. $this->_oModule->onSubscriptionCancel($aPending, $aSubscription, ['reason' => $sReason]);
  456. return true;
  457. }
  458. public function getPopupCancelSurvey($iId)
  459. {
  460. $CNF = &$this->_oModule->_oConfig->CNF;
  461. $oForm = $this->_getFormCancelSurvey($iId);
  462. $oForm->initChecker();
  463. if($oForm->isSubmittedAndValid()) {
  464. $aReasons = BxDolForm::getDataItems($CNF['OBJECT_FORM_PRELISTS_REASONS_CANCEL']);
  465. return [
  466. 'code' => 0,
  467. 'msg' => ($sOther = $oForm->getCleanValue('other')) ? $sOther : $aReasons[$oForm->getCleanValue('items')]
  468. ];
  469. }
  470. $sPopupId = $this->_oModule->_oConfig->getHtmlIds('subscription', 'popup_subscription_cancel_survay') . $iId;
  471. $sPopupContent = BxTemplFunctions::getInstance()->transBox($sPopupId, $this->_oModule->_oTemplate->parseHtmlByName('subscription_form.html', [
  472. 'form_id' => $oForm->aFormAttrs['id'],
  473. 'form' => $oForm->getCode(true)
  474. ]));
  475. return ['code' => 1, 'popup' => ['html' => $sPopupContent, 'options' => ['closeOnOuterClick' => false]]];
  476. }
  477. protected function _getBlock($sType)
  478. {
  479. $CNF = &$this->_oModule->_oConfig->CNF;
  480. $sMethod = 'displayBlockSbs' . bx_gen_method_name($sType);
  481. if(!$this->_oModule->_oTemplate->isMethodExists($sMethod))
  482. return $this->_bIsApi ? [] : [
  483. 'content' => MsgBox(_t('_Empty'))
  484. ];
  485. $iUserId = $this->_oModule->getProfileId();
  486. if(empty($iUserId))
  487. return $this->_bIsApi ? [] : [
  488. 'content' => MsgBox(_t($CNF['T']['ERR_REQUIRED_LOGIN']))
  489. ];
  490. $mixedBlockContent = $this->_oModule->_oTemplate->$sMethod($iUserId);
  491. if($this->_bIsApi)
  492. return !$mixedBlockContent ? [] : [
  493. bx_api_get_block('grid', $mixedBlockContent)
  494. ];
  495. $this->_oModule->setSiteSubmenu('menu_dashboard', 'system', 'dashboard-subscriptions');
  496. $sBlockSubmenu = $this->_oModule->_oConfig->getObject('menu_sbs_submenu');
  497. $oBlockSubmenu = BxDolMenu::getObjectInstance($sBlockSubmenu);
  498. if($oBlockSubmenu)
  499. $oBlockSubmenu->setSelected($this->MODULE, 'sbs-' . str_replace('_', '-', $sType));
  500. return [
  501. 'content' => $mixedBlockContent,
  502. 'menu' => $this->_oModule->_oConfig->getObject('menu_sbs_submenu')
  503. ];
  504. }
  505. private function _getInterval($iPeriod, $sPeriodUnit, $iTrial = 0)
  506. {
  507. if((int)$iTrial > 0)
  508. return 'P' . $iTrial . 'D';
  509. $sInterval = '';
  510. switch($sPeriodUnit) {
  511. case BX_PAYMENT_SBS_PU_YEAR:
  512. $sInterval = 'P' . $iPeriod . 'Y';
  513. break;
  514. case BX_PAYMENT_SBS_PU_MONTH:
  515. $sInterval = 'P' . $iPeriod . 'M';
  516. break;
  517. case BX_PAYMENT_SBS_PU_WEEK:
  518. $sInterval = 'P' . (7 * $iPeriod) . 'D';
  519. break;
  520. case BX_PAYMENT_SBS_PU_DAY:
  521. $sInterval = 'P' . $iPeriod . 'D';
  522. break;
  523. case BX_PAYMENT_SBS_PU_HOUR:
  524. $sInterval = 'PT' . $iPeriod . 'H';
  525. break;
  526. case BX_PAYMENT_SBS_PU_MINUTE:
  527. $sInterval = 'PT' . $iPeriod . 'I';
  528. break;
  529. }
  530. return $sInterval;
  531. }
  532. protected function _getFormCancelSurvey($iId)
  533. {
  534. $CNF = &$this->_oModule->_oConfig->CNF;
  535. $sJsObject = $this->_oModule->_oConfig->getJsObject('subscription');
  536. $aReasons = BxDolForm::getDataItems($CNF['OBJECT_FORM_PRELISTS_REASONS_CANCEL']);
  537. $aForm = [
  538. 'form_attrs' => [
  539. 'id' => $this->_oModule->_oConfig->getHtmlIds('subscription', 'form_subscription_cancel_survay') . $iId,
  540. 'action' => BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'subscription_cancel/' . $iId,
  541. 'method' => BX_DOL_FORM_METHOD_DEFAULT,
  542. 'onsubmit' => 'return ' . $sJsObject . '.onSubmitCancelationReason(this)'
  543. ],
  544. 'params' => [
  545. 'db' => [
  546. 'table' => '',
  547. 'key' => '',
  548. 'uri' => '',
  549. 'uri_title' => '',
  550. 'submit_name' => 'do_submit'
  551. ],
  552. ],
  553. 'inputs' => [
  554. 'items' => [
  555. 'type' => 'radio_set',
  556. 'name' => 'items',
  557. 'caption' => _t('_bx_payment_form_cs_input_items'),
  558. 'values' => $aReasons,
  559. 'value' => key($aReasons),
  560. 'required' => '1',
  561. 'attrs' => [
  562. 'onchange' => $sJsObject . '.onChangeCancelationReason(this)'
  563. ],
  564. 'db' => [
  565. 'pass' => 'Xss',
  566. ],
  567. 'checker' => [
  568. 'func' => 'Avail',
  569. 'params' => [],
  570. 'error' => _t('_bx_payment_form_input_err'),
  571. ],
  572. ],
  573. 'other' => [
  574. 'type' => 'text',
  575. 'name' => 'other',
  576. 'caption' => _t('_bx_payment_form_cs_input_other'),
  577. 'value' => '',
  578. 'required' => '1',
  579. 'tr_attrs' => [
  580. 'class' => 'bx-payment-cs-other bx-payment-cs-hidden'
  581. ],
  582. 'db' => [
  583. 'pass' => 'Xss',
  584. ],
  585. ],
  586. 'controls' => [
  587. 'name' => 'controls',
  588. 'type' => 'input_set',
  589. [
  590. 'type' => 'submit',
  591. 'name' => 'do_submit',
  592. 'value' => _t('_bx_payment_form_cs_input_submit'),
  593. ], [
  594. 'type' => 'reset',
  595. 'name' => 'do_cancel',
  596. 'value' => _t('_bx_payment_form_cs_input_cancel'),
  597. 'attrs' => [
  598. 'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
  599. 'class' => 'bx-def-margin-sec-left',
  600. ],
  601. ]
  602. ]
  603. ]
  604. ];
  605. return new BxTemplFormView($aForm);
  606. }
  607. }
  608. /** @} */