1: <?php
2: /**
3: * Magento
4: *
5: * NOTICE OF LICENSE
6: *
7: * This source file is subject to the Open Software License (OSL 3.0)
8: * that is bundled with this package in the file LICENSE.txt.
9: * It is also available through the world-wide-web at this URL:
10: * http://opensource.org/licenses/osl-3.0.php
11: * If you did not receive a copy of the license and are unable to
12: * obtain it through the world-wide-web, please send an email
13: * to license@magentocommerce.com so we can send you a copy immediately.
14: *
15: * DISCLAIMER
16: *
17: * Do not edit or add to this file if you wish to upgrade Magento to newer
18: * versions in the future. If you wish to customize Magento for your
19: * needs please refer to http://www.magentocommerce.com for more information.
20: *
21: * @category Mage
22: * @package Mage_Sales
23: * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24: * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25: */
26:
27: /**
28: * Billing Agreement abstract model
29: *
30: * @method Mage_Sales_Model_Resource_Billing_Agreement _getResource()
31: * @method Mage_Sales_Model_Resource_Billing_Agreement getResource()
32: * @method int getCustomerId()
33: * @method Mage_Sales_Model_Billing_Agreement setCustomerId(int $value)
34: * @method string getMethodCode()
35: * @method Mage_Sales_Model_Billing_Agreement setMethodCode(string $value)
36: * @method string getReferenceId()
37: * @method Mage_Sales_Model_Billing_Agreement setReferenceId(string $value)
38: * @method string getStatus()
39: * @method Mage_Sales_Model_Billing_Agreement setStatus(string $value)
40: * @method string getCreatedAt()
41: * @method Mage_Sales_Model_Billing_Agreement setCreatedAt(string $value)
42: * @method string getUpdatedAt()
43: * @method Mage_Sales_Model_Billing_Agreement setUpdatedAt(string $value)
44: * @method int getStoreId()
45: * @method Mage_Sales_Model_Billing_Agreement setStoreId(int $value)
46: * @method string getAgreementLabel()
47: * @method Mage_Sales_Model_Billing_Agreement setAgreementLabel(string $value)
48: *
49: * @category Mage
50: * @package Mage_Sales
51: * @author Magento Core Team <core@magentocommerce.com>
52: */
53: class Mage_Sales_Model_Billing_Agreement extends Mage_Payment_Model_Billing_AgreementAbstract
54: {
55: const STATUS_ACTIVE = 'active';
56: const STATUS_CANCELED = 'canceled';
57:
58: /**
59: * Related agreement orders
60: *
61: * @var array
62: */
63: protected $_relatedOrders = array();
64:
65: /**
66: * Init model
67: *
68: */
69: protected function _construct()
70: {
71: $this->_init('sales/billing_agreement');
72: }
73:
74: /**
75: * Set created_at parameter
76: *
77: * @return Mage_Core_Model_Abstract
78: */
79: protected function _beforeSave()
80: {
81: $date = Mage::getModel('core/date')->gmtDate();
82: if ($this->isObjectNew() && !$this->getCreatedAt()) {
83: $this->setCreatedAt($date);
84: } else {
85: $this->setUpdatedAt($date);
86: }
87: return parent::_beforeSave();
88: }
89:
90: /**
91: * Save agreement order relations
92: *
93: * @return Mage_Core_Model_Abstract
94: */
95: protected function _afterSave()
96: {
97: if (!empty($this->_relatedOrders)) {
98: $this->_saveOrderRelations();
99: }
100: return parent::_afterSave();
101: }
102:
103: /**
104: * Retrieve billing agreement status label
105: *
106: * @return string
107: */
108: public function getStatusLabel()
109: {
110: switch ($this->getStatus()) {
111: case self::STATUS_ACTIVE:
112: return Mage::helper('sales')->__('Active');
113: case self::STATUS_CANCELED:
114: return Mage::helper('sales')->__('Canceled');
115: }
116: }
117:
118: /**
119: * Initialize token
120: *
121: * @return string
122: */
123: public function initToken()
124: {
125: $this->getPaymentMethodInstance()
126: ->initBillingAgreementToken($this);
127: return $this->getRedirectUrl();
128: }
129:
130: /**
131: * Get billing agreement details
132: * Data from response is inside this object
133: *
134: * @return Mage_Sales_Model_Billing_Agreement
135: */
136: public function verifyToken()
137: {
138: $this->getPaymentMethodInstance()
139: ->getBillingAgreementTokenInfo($this);
140: return $this;
141: }
142:
143: /**
144: * Create billing agreement
145: *
146: * @return Mage_Sales_Model_Billing_Agreement
147: */
148: public function place()
149: {
150: $this->verifyToken();
151:
152: $paymentMethodInstance = $this->getPaymentMethodInstance()
153: ->placeBillingAgreement($this);
154:
155: $this->setCustomerId($this->getCustomer()->getId())
156: ->setMethodCode($this->getMethodCode())
157: ->setReferenceId($this->getBillingAgreementId())
158: ->setStatus(self::STATUS_ACTIVE)
159: ->setAgreementLabel($paymentMethodInstance->getTitle())
160: ->save();
161: return $this;
162: }
163:
164: /**
165: * Cancel billing agreement
166: *
167: * @return Mage_Sales_Model_Billing_Agreement
168: */
169: public function cancel()
170: {
171: $this->setStatus(self::STATUS_CANCELED);
172: $this->getPaymentMethodInstance()->updateBillingAgreementStatus($this);
173: return $this->save();
174: }
175:
176: /**
177: * Check whether can cancel billing agreement
178: *
179: * @return bool
180: */
181: public function canCancel()
182: {
183: return ($this->getStatus() != self::STATUS_CANCELED);
184: }
185:
186: /**
187: * Retrieve billing agreement statuses array
188: *
189: * @return array
190: */
191: public function getStatusesArray()
192: {
193: return array(
194: self::STATUS_ACTIVE => Mage::helper('sales')->__('Active'),
195: self::STATUS_CANCELED => Mage::helper('sales')->__('Canceled')
196: );
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[] = Mage::helper('payment')->__('Customer ID is not set.');
209: }
210: if (!$this->getStatus()) {
211: $this->_errors[] = Mage::helper('payment')->__('Billing Agreement status is not set.');
212: }
213: return $result && empty($this->_errors);
214: }
215:
216: /**
217: * Import payment data to billing agreement
218: *
219: * $payment->getBillingAgreementData() contains array with following structure :
220: * [billing_agreement_id] => string
221: * [method_code] => string
222: *
223: * @param Mage_Sales_Model_Order_Payment $payment
224: * @return Mage_Sales_Model_Billing_Agreement
225: */
226: public function importOrderPayment(Mage_Sales_Model_Order_Payment $payment)
227: {
228: $baData = $payment->getBillingAgreementData();
229:
230: $this->_paymentMethodInstance = (isset($baData['method_code']))
231: ? Mage::helper('payment')->getMethodInstance($baData['method_code'])
232: : $payment->getMethodInstance();
233: if ($this->_paymentMethodInstance) {
234: $this->_paymentMethodInstance->setStore($payment->getMethodInstance()->getStore());
235: $this->setCustomerId($payment->getOrder()->getCustomerId())
236: ->setMethodCode($this->_paymentMethodInstance->getCode())
237: ->setReferenceId($baData['billing_agreement_id'])
238: ->setStatus(self::STATUS_ACTIVE);
239: }
240: return $this;
241: }
242:
243: /**
244: * Retrieve available customer Billing Agreements
245: *
246: * @param int $customer
247: * @return Mage_Paypal_Controller_Express_Abstract
248: */
249: public function getAvailableCustomerBillingAgreements($customerId)
250: {
251: $collection = Mage::getResourceModel('sales/billing_agreement_collection');
252: $collection->addFieldToFilter('customer_id', $customerId)
253: ->addFieldToFilter('status', self::STATUS_ACTIVE)
254: ->setOrder('agreement_id');
255: return $collection;
256: }
257:
258: /**
259: * Check whether need to create billing agreement for customer
260: *
261: * @param int $customerId
262: * @return bool
263: */
264: public function needToCreateForCustomer($customerId)
265: {
266: return $customerId ? count($this->getAvailableCustomerBillingAgreements($customerId)) == 0 : false;
267: }
268:
269: /**
270: * Add order relation to current billing agreement
271: *
272: * @param int|Mage_Sales_Model_Order $orderId
273: * @return Mage_Sales_Model_Billing_Agreement
274: */
275: public function addOrderRelation($orderId)
276: {
277: $this->_relatedOrders[] = $orderId;
278: return $this;
279: }
280:
281: /**
282: * Save related orders
283: */
284: protected function _saveOrderRelations()
285: {
286: foreach ($this->_relatedOrders as $order) {
287: $orderId = $order instanceof Mage_Sales_Model_Order ? $order->getId() : (int) $order;
288: $this->getResource()->addOrderRelation($this->getId(), $orderId);
289: }
290: }
291:
292: }
293: