1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
52: class Mage_Paypal_Model_Report_Settlement extends Mage_Core_Model_Abstract
53: {
54: 55: 56: 57:
58: const REPORTS_HOSTNAME = "reports.paypal.com";
59:
60: 61: 62: 63:
64: const SANDBOX_REPORTS_HOSTNAME = "reports.sandbox.paypal.com";
65:
66: 67: 68: 69:
70: const REPORTS_PATH = "/ppreports/outgoing";
71:
72: 73: 74: 75:
76: const FILES_IN_CHARSET = "UTF-16";
77:
78: 79: 80: 81:
82: const FILES_OUT_CHARSET = "UTF-8";
83:
84: 85: 86: 87:
88: protected $_rows = array();
89:
90: protected $_csvColumns = array(
91: 'old' => array(
92: 'section_columns' => array(
93: '' => 0,
94: 'TransactionID' => 1,
95: 'InvoiceID' => 2,
96: 'PayPalReferenceID' => 3,
97: 'PayPalReferenceIDType' => 4,
98: 'TransactionEventCode' => 5,
99: 'TransactionInitiationDate' => 6,
100: 'TransactionCompletionDate' => 7,
101: 'TransactionDebitOrCredit' => 8,
102: 'GrossTransactionAmount' => 9,
103: 'GrossTransactionCurrency' => 10,
104: 'FeeDebitOrCredit' => 11,
105: 'FeeAmount' => 12,
106: 'FeeCurrency' => 13,
107: 'CustomField' => 14,
108: 'ConsumerID' => 15
109: ),
110: 'rowmap' => array(
111: 'TransactionID' => 'transaction_id',
112: 'InvoiceID' => 'invoice_id',
113: 'PayPalReferenceID' => 'paypal_reference_id',
114: 'PayPalReferenceIDType' => 'paypal_reference_id_type',
115: 'TransactionEventCode' => 'transaction_event_code',
116: 'TransactionInitiationDate' => 'transaction_initiation_date',
117: 'TransactionCompletionDate' => 'transaction_completion_date',
118: 'TransactionDebitOrCredit' => 'transaction_debit_or_credit',
119: 'GrossTransactionAmount' => 'gross_transaction_amount',
120: 'GrossTransactionCurrency' => 'gross_transaction_currency',
121: 'FeeDebitOrCredit' => 'fee_debit_or_credit',
122: 'FeeAmount' => 'fee_amount',
123: 'FeeCurrency' => 'fee_currency',
124: 'CustomField' => 'custom_field',
125: 'ConsumerID' => 'consumer_id'
126: )
127: ),
128: 'new' => array(
129: 'section_columns' => array(
130: '' => 0,
131: 'Transaction ID' => 1,
132: 'Invoice ID' => 2,
133: 'PayPal Reference ID' => 3,
134: 'PayPal Reference ID Type' => 4,
135: 'Transaction Event Code' => 5,
136: 'Transaction Initiation Date' => 6,
137: 'Transaction Completion Date' => 7,
138: 'Transaction Debit or Credit' => 8,
139: 'Gross Transaction Amount' => 9,
140: 'Gross Transaction Currency' => 10,
141: 'Fee Debit or Credit' => 11,
142: 'Fee Amount' => 12,
143: 'Fee Currency' => 13,
144: 'Custom Field' => 14,
145: 'Consumer ID' => 15,
146: 'Payment Tracking ID' => 16
147: ),
148: 'rowmap' => array(
149: 'Transaction ID' => 'transaction_id',
150: 'Invoice ID' => 'invoice_id',
151: 'PayPal Reference ID' => 'paypal_reference_id',
152: 'PayPal Reference ID Type' => 'paypal_reference_id_type',
153: 'Transaction Event Code' => 'transaction_event_code',
154: 'Transaction Initiation Date' => 'transaction_initiation_date',
155: 'Transaction Completion Date' => 'transaction_completion_date',
156: 'Transaction Debit or Credit' => 'transaction_debit_or_credit',
157: 'Gross Transaction Amount' => 'gross_transaction_amount',
158: 'Gross Transaction Currency' => 'gross_transaction_currency',
159: 'Fee Debit or Credit' => 'fee_debit_or_credit',
160: 'Fee Amount' => 'fee_amount',
161: 'Fee Currency' => 'fee_currency',
162: 'Custom Field' => 'custom_field',
163: 'Consumer ID' => 'consumer_id',
164: 'Payment Tracking ID' => 'payment_tracking_id'
165: )
166: )
167: );
168: 169: 170:
171: protected function _construct()
172: {
173: $this->_init('paypal/report_settlement');
174: }
175:
176: 177: 178: 179: 180:
181: protected function _beforeSave()
182: {
183: $this->_dataSaveAllowed = true;
184: if ($this->getId()) {
185: if ($this->getLastModified() == $this->getReportLastModified()) {
186: $this->_dataSaveAllowed = false;
187: }
188: }
189: $this->setLastModified($this->getReportLastModified());
190: return parent::_beforeSave();
191: }
192:
193: 194: 195: 196: 197: 198: 199:
200: public function fetchAndSave($config)
201: {
202: $connection = new Varien_Io_Sftp();
203: $connection->open(array(
204: 'host' => $config['hostname'],
205: 'username' => $config['username'],
206: 'password' => $config['password']
207: ));
208: $connection->cd($config['path']);
209: $fetched = 0;
210: $listing = $this->_filterReportsList($connection->rawls());
211: foreach ($listing as $filename => $attributes) {
212: $localCsv = tempnam(Mage::getConfig()->getOptions()->getTmpDir(), 'PayPal_STL');
213: if ($connection->read($filename, $localCsv)) {
214: if (!is_writable($localCsv)) {
215: Mage::throwException(Mage::helper('paypal')->__('Cannot create target file for reading reports.'));
216: }
217:
218: $encoded = file_get_contents($localCsv);
219: $csvFormat = 'new';
220: if (self::FILES_OUT_CHARSET != mb_detect_encoding(($encoded))) {
221: $decoded = @iconv(self::FILES_IN_CHARSET, self::FILES_OUT_CHARSET.'//IGNORE', $encoded);
222: file_put_contents($localCsv, $decoded);
223: $csvFormat = 'old';
224: }
225:
226:
227: if (isset($attributes['mtime'])) {
228: $lastModified = new Zend_Date($attributes['mtime']);
229: $this->setReportLastModified($lastModified->toString(Varien_Date::DATETIME_INTERNAL_FORMAT));
230: }
231:
232: $this->setReportDate($this->_fileNameToDate($filename))
233: ->setFilename($filename)
234: ->parseCsv($localCsv, $csvFormat);
235:
236: if ($this->getAccountId()) {
237: $this->save();
238: }
239:
240: if ($this->_dataSaveAllowed) {
241: $fetched += count($this->_rows);
242: }
243:
244: $this->unsetData();
245: unlink($localCsv);
246: }
247: }
248: return $fetched;
249: }
250:
251: 252: 253: 254: 255: 256: 257:
258: public function parseCsv($localCsv, $format = 'new')
259: {
260: $this->_rows = array();
261:
262: $sectionColumns = $this->_csvColumns[$format]['section_columns'];
263: $rowMap = $this->_csvColumns[$format]['rowmap'];
264:
265: $flippedSectionColumns = array_flip($sectionColumns);
266: $fp = fopen($localCsv, 'r');
267: while($line = fgetcsv($fp)) {
268: if (empty($line)) {
269: continue;
270: }
271: $lineType = $line[0];
272: switch($lineType) {
273: case 'RH':
274: $lastModified = new Zend_Date($line[1]);
275: $this->setReportLastModified($lastModified->toString(Varien_Date::DATETIME_INTERNAL_FORMAT));
276:
277: break;
278: case 'FH':
279:
280: break;
281: case 'SH':
282: $this->setAccountId($line[3]);
283: $this->loadByAccountAndDate();
284: break;
285: case 'CH':
286:
287:
288: for ($i = 1; $i < count($line); $i++) {
289: $sectionColumns[$line[$i]] = $i;
290: }
291: $flippedSectionColumns = array_flip($sectionColumns);
292: break;
293: case 'SB':
294: $bodyItem = array();
295: for($i = 1; $i < count($line); $i++) {
296: $bodyItem[$rowMap[$flippedSectionColumns[$i]]] = $line[$i];
297: }
298: $this->_rows[] = $bodyItem;
299: break;
300: case 'SC':
301: case 'RC':
302: case 'SF':
303: case 'FF':
304: case 'RF':
305:
306: break;
307: }
308: }
309: return $this;
310: }
311:
312: 313: 314: 315: 316:
317: public function loadByAccountAndDate()
318: {
319: $this->getResource()->loadByAccountAndDate($this, $this->getAccountId(), $this->getReportDate());
320: return $this;
321: }
322:
323: 324: 325: 326: 327:
328: public function getRows()
329: {
330: return $this->_rows;
331: }
332:
333: 334: 335: 336: 337: 338:
339: public function getFieldLabel($field)
340: {
341: switch ($field) {
342: case 'report_date':
343: return Mage::helper('paypal')->__('Report Date');
344: case 'account_id':
345: return Mage::helper('paypal')->__('Merchant Account');
346: case 'transaction_id':
347: return Mage::helper('paypal')->__('Transaction ID');
348: case 'invoice_id':
349: return Mage::helper('paypal')->__('Invoice ID');
350: case 'paypal_reference_id':
351: return Mage::helper('paypal')->__('PayPal Reference ID');
352: case 'paypal_reference_id_type':
353: return Mage::helper('paypal')->__('PayPal Reference ID Type');
354: case 'transaction_event_code':
355: return Mage::helper('paypal')->__('Event Code');
356: case 'transaction_event':
357: return Mage::helper('paypal')->__('Event');
358: case 'transaction_initiation_date':
359: return Mage::helper('paypal')->__('Initiation Date');
360: case 'transaction_completion_date':
361: return Mage::helper('paypal')->__('Completion Date');
362: case 'transaction_debit_or_credit':
363: return Mage::helper('paypal')->__('Debit or Credit');
364: case 'gross_transaction_amount':
365: return Mage::helper('paypal')->__('Gross Amount');
366: case 'fee_debit_or_credit':
367: return Mage::helper('paypal')->__('Fee Debit or Credit');
368: case 'fee_amount':
369: return Mage::helper('paypal')->__('Fee Amount');
370: case 'custom_field':
371: return Mage::helper('paypal')->__('Custom');
372: default:
373: return $field;
374: }
375: }
376:
377: 378: 379: 380: 381: 382: 383:
384: public function getSftpCredentials($automaticMode = false)
385: {
386: $configs = array();
387: $uniques = array();
388: foreach(Mage::app()->getStores() as $store) {
389:
390: $active = (bool)$store->getConfig('paypal/fetch_reports/active');
391: if (!$active && $automaticMode) {
392: continue;
393: }
394: $cfg = array(
395: 'hostname' => $store->getConfig('paypal/fetch_reports/ftp_ip'),
396: 'path' => $store->getConfig('paypal/fetch_reports/ftp_path'),
397: 'username' => $store->getConfig('paypal/fetch_reports/ftp_login'),
398: 'password' => $store->getConfig('paypal/fetch_reports/ftp_password'),
399: 'sandbox' => $store->getConfig('paypal/fetch_reports/ftp_sandbox'),
400: );
401: if (empty($cfg['username']) || empty($cfg['password'])) {
402: continue;
403: }
404: if (empty($cfg['hostname']) || $cfg['sandbox']) {
405: $cfg['hostname'] = $cfg['sandbox'] ? self::SANDBOX_REPORTS_HOSTNAME : self::REPORTS_HOSTNAME;
406: }
407: if (empty($cfg['path']) || $cfg['sandbox']) {
408: $cfg['path'] = self::REPORTS_PATH;
409: }
410:
411: if (in_array(serialize($cfg), $uniques)) {
412: continue;
413: }
414: $uniques[] = serialize($cfg);
415: $configs[] = $cfg;
416: }
417: return $configs;
418: }
419:
420: 421: 422: 423: 424: 425:
426: protected function _fileNameToDate($filename)
427: {
428:
429: $dateSnippet = substr(basename($filename), 4, 8);
430: $result = substr($dateSnippet, 0, 4).'-'.substr($dateSnippet, 4, 2).'-'.substr($dateSnippet, 6, 2);
431: return $result;
432: }
433:
434: 435: 436: 437: 438: 439:
440: protected function _filterReportsList($list)
441: {
442: $result = array();
443: $pattern = '/^STL-(\d{8,8})\.(\d{2,2})\.(.{3,3})\.CSV$/';
444: foreach ($list as $filename => $data) {
445: if (preg_match($pattern, $filename)) {
446: $result[$filename] = $data;
447: }
448: }
449: return $result;
450: }
451: }
452: