def iter_transactions(self): for row in self.doc.xpath('//tr/th[@headers=' '"postedHeader transactionDateHeader"]/..'): tdate = row.xpath('th[@headers="postedHeader ' 'transactionDateHeader"]/text()')[0] pdate = row.xpath('td[@headers="postedHeader ' 'postingDateHeader"]/text()')[0] desc = row.xpath('td[@headers="postedHeader ' 'descriptionHeader"]/span/text()')[0] ref = row.xpath('td[@headers="postedHeader ' 'descriptionHeader"]/text()')[0] amount = row.xpath('td[@headers="postedHeader ' 'amountHeader"]/text()')[0] tdate = datetime.datetime.strptime(tdate, '%m/%d/%y') pdate = datetime.datetime.strptime(pdate, '%m/%d/%y') desc = clean_label(desc) ref = re.match('.*<REFERENCE ([^>]+)>.*', ref).group(1) if amount.startswith('+'): amount = AmTr.decimal_amount(amount[1:]) else: amount = -AmTr.decimal_amount(amount) trans = Transaction(ref) trans.date = tdate trans.rdate = pdate trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = amount yield trans
def iter_transactions(self): for row in self.doc.xpath('//tr/th[@headers=' '"postedHeader dateHeader"]/..'): date = row.xpath('th[@headers="postedHeader ' 'dateHeader"]/text()')[0] desc = row.xpath('td[@headers="postedHeader ' 'descriptionHeader"]/span/text()')[0] deposit = row.xpath('td[@headers="postedHeader ' 'depositsConsumerHeader"]/span/text()')[0] withdraw = row.xpath('td[@headers="postedHeader ' 'withdrawalsConsumerHeader"]/span/text()')[0] date = datetime.datetime.strptime(date, '%m/%d/%y') desc = clean_label(desc) deposit = deposit.strip() deposit = AmTr.decimal_amount(deposit or '0') withdraw = withdraw.strip() withdraw = AmTr.decimal_amount(withdraw or '0') amount = deposit - withdraw trans = Transaction(u'') trans.date = date trans.rdate = date trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = amount yield trans
def account(self): label = u' '.join(self.doc.xpath( '//div[contains(@class,"myCreditCardDetails")]')[0]\ .text_content().split()) balance = self.amount(u'Balance') cardlimit = self.doc.xpath( u'//li[text()="Available to Spend"]')[0].text_content()\ .replace(u'Available to Spend', u'').replace(u'Limit', u'').strip() paymin = self.amount(u'Payment Due') if self.doc.xpath(u'//li[@class="noPaymentDue"]'): # If payment date is not scheduled yet, set it somewhere in a # distant future, so that we always have a valid date. paydate = datetime.now() + timedelta(days=999) else: rawtext = self.doc.xpath( u'//li[contains(text(),"Due Date")]')[0].text_content() datetext = re.match('.*(\d\d/\d\d/\d\d\d\d).*', rawtext).group(1) paydate = datetime.strptime(datetext, '%m/%d/%Y') a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) if paydate is not None: a.paydate = paydate return a
def unsorted_trans(self): for jnl in self.doc['accountDetailsAndActivity']['accountActivity'] \ ['postedTransactionJournals']: tdate = jnl['columns'][0]['activityColumn'][0] label = jnl['columns'][1]['activityColumn'][0] amount = jnl['columns'][3]['activityColumn'][0] xdescs = dict((x['label'], x['value'][0]) for x in jnl['extendedDescriptions']) pdate = xdescs['Posted Date :'] ref = xdescs.get('Reference Number:') or '' if amount.startswith('(') and amount.endswith(')'): amount = AmTr.decimal_amount(amount[1:-1]) else: amount = -AmTr.decimal_amount(amount) label = clean_label(label) trans = Transaction(ref) trans.date = datetime.strptime(tdate, '%m-%d-%Y') trans.rdate = datetime.strptime(pdate, '%m-%d-%Y') trans.type = Transaction.TYPE_UNKNOWN trans.raw = label trans.label = label trans.amount = amount yield trans
def account(self): id_ = self.doc.xpath( u'//strong[contains(text(),' '"credit card account ending in")]/text()')[0].strip()[-4:] balance = self.doc.xpath( u'//section[@id=" account_summary"]' '//span[text()="Current Balance"]/../span[2]/text()')[0].strip() cardlimit = self.doc.xpath(u'//span[contains(text(),"Credit limit")]' '/text()')[0].split()[-1] paymin = self.doc.xpath( u'//section[@id=" account_summary"]' '//strong[text()="Minimum Payment Due"]/../../span[2]/text()' )[0].strip() a = Account() a.id = id_ a.label = u'ACCOUNT ENDING IN %s' % id_ a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) #TODO: Add paydate. #Oleg: I don't have an account with scheduled payment. # Need to wait for a while... return a
def unsorted_trans(self): for jnl in self.doc['accountDetailsAndActivity']['accountActivity'] \ ['postedTransactionJournals']: tdate = jnl['columns'][0]['activityColumn'][0] label = jnl['columns'][1]['activityColumn'][0] amount = jnl['columns'][3]['activityColumn'][0] xdescs = dict((x['label'], x['value'][0]) for x in jnl['extendedDescriptions']) pdate = xdescs[u'Posted Date :'] ref = xdescs.get(u'Reference Number:') or u'' if amount.startswith(u'(') and amount.endswith(u')'): amount = AmTr.decimal_amount(amount[1:-1]) else: amount = -AmTr.decimal_amount(amount) label = clean_label(label) trans = Transaction(ref) trans.date = datetime.strptime(tdate, '%m-%d-%Y') trans.rdate = datetime.strptime(pdate, '%m-%d-%Y') trans.type = Transaction.TYPE_UNKNOWN trans.raw = label trans.label = label trans.amount = amount yield trans
def iter_transactions(self): for row in self.doc.xpath('//tr/th[@headers=' '"postedHeader dateHeader"]/..'): date = row.xpath('th[@headers="postedHeader ' 'dateHeader"]/text()')[0] desc = row.xpath('td[@headers="postedHeader descriptionHeader"]' '//span[@class="OneLinkNoTx"]/text()')[0] deposit = row.xpath('td[@headers="postedHeader ' 'depositsConsumerHeader"]/span/text()')[0] withdraw = row.xpath('td[@headers="postedHeader ' 'withdrawalsConsumerHeader"]/span/text()')[0] date = datetime.datetime.strptime(date, '%m/%d/%y') desc = clean_label(desc) deposit = deposit.strip() deposit = AmTr.decimal_amount(deposit or '0') withdraw = withdraw.strip() withdraw = AmTr.decimal_amount(withdraw or '0') amount = deposit - withdraw trans = Transaction(u'') trans.date = date trans.rdate = date trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = amount yield trans
def account(self): label = u' '.join( self.doc.xpath('//div[contains(@class,"myCreditCardDetails")]') [0].text_content().split()) balance = self.amount(u'Balance') cardlimit = self.doc.xpath( u'//li[text()="Available to Spend"]')[0].text_content()\ .replace(u'Available to Spend', u'').replace(u'Limit', u'').strip() paymin = self.amount(u'Payment Due') if self.doc.xpath(u'//li[@class="noPaymentDue"]'): # If payment date is not scheduled yet, set it somewhere in a # distant future, so that we always have a valid date. paydate = datetime.now() + timedelta(days=999) else: rawtext = self.doc.xpath( u'//li[contains(text(),"Due Date")]')[0].text_content() datetext = re.match('.*(\d\d/\d\d/\d\d\d\d).*', rawtext).group(1) paydate = datetime.strptime(datetext, '%m/%d/%Y') a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) if paydate is not None: a.paydate = paydate return a
def amount(self, shmt, name): for root in shmt.xpath(u'../../../../../../../..' u'//td[text()="Item(s) Subtotal: "]/../..'): for node in root.xpath(u'tr/td[text()="%s"]' % name): return AmTr.decimal_amount( node.xpath('../td')[-1].text.strip()) for node in root.xpath(u'tr/td/b[text()="%s"]' % name): return AmTr.decimal_amount( node.xpath('../../td/b')[-1].text.strip()) return Decimal(0)
def shipping(self): if self.doc.xpath('//tr[@id="shipping_fee_row"]' '//span[@class="free_shipping"]'): amount = '0' else: amount = self.doc.xpath('//span[@id="shipping_fee"]/text()')[0] return AmTr.decimal_amount(amount)
def read_indent_amount(self, pos, range_skip=(0, 0), range_plus=(0, 0), range_minus=(0, 0)): startPos = pos # Read layout-amount pairs. amounts = [] while True: prevPos = pos pos, layout = self.read_layout_tm(pos) pos, amount = self.read_amount(pos) if layout is None or amount is None: pos = prevPos break else: amounts.append((layout, amount)) if not amounts: return startPos, None else: # Infer amount type by its indentation in the layout. amount_total = AmTr.decimal_amount('0') for (_, _, _, _, indent, _), amount in amounts: within = lambda xmin_xmax: xmin_xmax[0] <= indent <= xmin_xmax[ 1] if within(range_skip): continue elif within(range_plus): amount_total += amount elif within(range_minus): amount_total -= amount return pos, amount_total
def read_indent_amount(self, pos, range_skip=(0,0), range_plus=(0,0), range_minus=(0,0)): startPos = pos # Read layout-amount pairs. amounts = [] while True: prevPos = pos pos, layout = self.read_layout_tm(pos) pos, amount = self.read_amount(pos) if layout is None or amount is None: pos = prevPos break else: amounts.append((layout, amount)) if not amounts: return startPos, None else: # Infer amount type by its indentation in the layout. amount_total = AmTr.decimal_amount('0') for (_, _, _, _, indent, _), amount in amounts: within = lambda xmin_xmax: xmin_xmax[0] <= indent <= xmin_xmax[1] if within(range_skip): continue elif within(range_plus): amount_total += amount elif within(range_minus): amount_total -= amount return pos, amount_total
def amount(self, *names): return Decimal( sum( AmTr.decimal_amount(amount.strip()) for n in names for amount in self.doc.xpath( '(//span[contains(text(),"%s:")]/../..//span)[2]/text()' % n)))
def items(self): for shmt in self.shipments(): root = shmt.xpath(u'../../../../../../../..' u'//b[text()="Items Ordered"]')[0] for item in root.xpath('../../../tr')[1:]: count = url = label = None for div in item.xpath('*//div'): m = re.match(u'^\s*(\d+)\s*of:(.*)$', div.text, re.MULTILINE + re.DOTALL) if not m: continue count = Decimal(m.group(1).strip()) label = unicode(m.group(2).strip()) if label: url = u'' else: a = div.xpath('*//a[contains(@href,"/gp/product")]')[0] url = unicode(a.attrib['href']) label = unicode(a.text.strip()) price1 = item.xpath('*//div')[-1].text.strip() price = count * AmTr.decimal_amount(price1) itm = Item() itm.label = label itm.url = url itm.price = price yield itm
def items(self): for item in self.doc.xpath('//div[contains(@class,"a-box shipment")]' '/div/div/div/div/div/div'): url = (item.xpath(u'*//a[contains(@href,"/gp/product")]/@href') + [u''])[0] label = u''.join( item.xpath( '*//a[contains(@href,"/gp/product")]/text()')).strip() price = u''.join( x.strip() for x in item.xpath('*//span[contains(text(),"$")]/text()')[:1] if x.strip().startswith('$')) price = AmTr.decimal_amount(price) multi = re.match(u'([0-9]+) of (.*)', label) if multi: amount, label = multi.groups() price *= Decimal(amount) if url: url = unicode(self.browser.BASEURL) + \ re.match(u'(/gp/product/.*)/ref=.*', url).group(1) if label: itm = Item() itm.label = label itm.url = url itm.price = price yield itm
def discount(self): TAGS = [ 'coupon_discount_amount', 'promo_discount_amount', 'total_rewards', 'applied_credit' ] return -sum( AmTr.decimal_amount(x[1:][:-1]) for tag in TAGS for x in self.doc.xpath('//span[@id="%s"]/text()' % tag))
def payment_part(self, which): # The numbers notation on VS is super wierd. # Sometimes negative amounts are represented by <em> element. for node in self.doc.xpath('//tbody[@class="payment-summary"]' '//td[contains(text(),"%s")]/../td[2]' % which): strv = node.text_content().strip() v = Decimal(0) if strv == u'FREE' else AmTr.decimal_amount(strv) return -v if node.xpath('em') and v > 0 else v return Decimal(0)
def iter_history_recent(self, account): self.start() if account.id != self._account_id(): raise AccountNotFound() self._account_link().click() self.wait_ajax() for span in self.find('span.cM-maximizeButton'): span.click() for tr in self.find('tr.payments,tr.purchase'): trdata = lambda n: tr.find_element_by_css_selector( 'td.cT-bodyTableColumn%i span.cT-line1' % n).text treid = tr.get_attribute('id').replace('rowID', 'rowIDExt') tredata = {} for tre in self.find('tr#%s' % treid): labels = [x.text for x in tre.find_elements_by_css_selector( 'div.cT-labelItem')] values = [x.text for x in tre.find_elements_by_css_selector( 'div.cT-valueItem')] tredata = dict(zip(labels, values)) ref = tredata.get(u'Reference Number:', u'') tdate = trdata(1) pdate = tredata.get(u'Posted Date :', tdate) desc = clean_label(trdata(2)) amount = trdata(4) tdate = datetime.datetime.strptime(tdate, '%m-%d-%Y') pdate = datetime.datetime.strptime(pdate, '%m-%d-%Y') if amount.startswith(u'(') and amount.endswith(u')'): amount = AmTr.decimal_amount(amount[1:-1]) else: amount = -AmTr.decimal_amount(amount) trans = Transaction(ref) trans.date = tdate trans.rdate = pdate trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = amount yield trans self.finish()
def account(self): detact = self.doc['accountDetailsAndActivity'] details = detact['accountDetails'] account = Account() account.type = Account.TYPE_CARD account.label = re.sub(r'<[^>]+>', '', detact['accountName']) account.id = account.label[-4:] for bal in details['accountBalances']: label, value = bal['label'], (bal['value'] or ['0'])[0] if label == u'Current Balance:': account.currency = Account.get_currency(value) account.balance = -AmTr.decimal_amount(value) elif label == u'Total Revolving Credit Line:': account.cardlimit = AmTr.decimal_amount(value) elif label.startswith(u'Minimum Payment Due'): d = re.match(r'.*(..-..-....):$', label).group(1) account.paydate = datetime.strptime(d, '%m-%d-%Y') account.paymin = AmTr.decimal_amount(value) return account
def account(self): detact = self.doc["accountDetailsAndActivity"] details = detact["accountDetails"] account = Account() account.type = Account.TYPE_CARD account.label = re.sub(r"<[^>]+>", "", detact["accountName"]) account.id = account.label[-4:] for bal in details["accountBalances"]: label, value = bal["label"], (bal["value"] or ["0"])[0] if label == u"Current Balance:": account.currency = Account.get_currency(value) account.balance = -AmTr.decimal_amount(value) elif label == u"Total Revolving Credit Line:": account.cardlimit = AmTr.decimal_amount(value) elif label.startswith(u"Minimum Payment Due"): d = re.match(r".*(..-..-....):$", label).group(1) account.paydate = datetime.strptime(d, "%m-%d-%Y") account.paymin = AmTr.decimal_amount(value) return account
def parse(self): emonths = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] date_format, time_format, months = self.guess_format() for row in self.document.xpath( '//table[@id="transactionTable"]/tbody/tr'): if len(row.xpath('.//td')) < 5: continue amount = row.xpath( './/td[@headers="gross"]')[-1].text_content().strip() if re.search('\d', amount): currency = Account.get_currency(amount) amount = AmTr.decimal_amount(amount) else: continue idtext = row.xpath('.//td[@class="detailsNoPrint"]//span[@class="accessAid"]')[0] \ .text_content().replace(u'\xa0', u' ').strip().rpartition(' ')[-1] trans = Transaction(idtext) trans.amount = amount trans._currency = currency datetext = row.xpath( './/td[@class="dateInfo"]')[0].text_content().strip() for i in range(0, 12): datetext = datetext.replace(months[i], emonths[i]) date = dateutil.parser.parse(datetext) trans.date = date trans.rdate = date trans.label = to_unicode( row.xpath('.//td[@class="emailInfo"]') [0].text_content().strip()) info = to_unicode( row.xpath('.//td[@class="paymentTypeInfo"]') [0].text_content().strip()) trans.raw = info + u' ' + trans.label if u'Authorization' in info or u'Autorisation' in info or \ u'Order' in info: continue if u'Credit Card' in trans.label or u'Carte bancaire' in trans.label: trans.type = Transaction.TYPE_CARD elif info.startswith(u'Payment') or info.startswith(u'Paiement'): trans.type = Transaction.TYPE_ORDER elif u'Currency Conversion' in info or u'Conversion de devise' in info: trans.type = Transaction.TYPE_BANK else: trans.type = Transaction.TYPE_UNKNOWN yield trans
def iter_accounts(self): self.start() bal = self.wait('div.cT-valueItem span.cT-balanceIndicator1')[0].text account = Account() account.id = self._account_id() account.label = self._account_link().text account.currency = Account.get_currency(bal) account.balance = -AmTr.decimal_amount(bal) account.type = Account.TYPE_CARD self.finish() yield account
def items(self): for tr in self.doc.xpath('//tbody[@class="order-items"]/tr'): label = tr.xpath('*//h1')[0].text_content().strip() price = AmTr.decimal_amount(re.match(r'^\s*([^\s]+)(\s+.*)?', tr.xpath('*//div[@class="price"]')[0].text_content(), re.DOTALL).group(1)) url = 'http:' + tr.xpath('*//img/@src')[0] item = Item() item.label = unicode(label) item.url = unicode(url) item.price = price yield item
def account(self): label = u' '.join(u''.join(self.doc.xpath( u'//text()[contains(.,"Account ending in")]')).split()) balance = self.doc.xpath( '//span[@id="currentBalance"]/..')[0].text_content() cardlimit = self.doc.xpath(u'//td[contains(text(),' '"Total Credit Limit")]/../td[2]')[0].text_content() paydate = self.doc.xpath(u'//td[contains(text(),' '"Payment Due Date")]/../td[2]')[0].text_content() paymin = self.doc.xpath( '//span[@id="nextMinPayment"]/..')[0].text_content() a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paydate = datetime.strptime(paydate, '%m/%d/%Y') a.paymin = AmTr.decimal_amount(paymin) return a
def account(self): id_ = self.doc.xpath(u'//strong[contains(text(),' '"credit card account ending in")]/text()')[0].strip()[-4:] balance = self.doc.xpath(u'//span[@class="description" and text()="Current Balance"]/../span[@class="total"]/text()')[0].strip() cardlimit = self.doc.xpath(u'//span[contains(text(),"Credit limit")]' '/text()')[0].split()[-1] paymin = self.doc.xpath(u'//section[@id=" account_summary"]' '//strong[text()="Minimum Payment Due"]/../../span[2]/text()' )[0].strip() a = Account() a.id = id_ a.label = u'ACCOUNT ENDING IN %s' % id_ a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD a.cardlimit = AmTr.decimal_amount(cardlimit) a.paymin = AmTr.decimal_amount(paymin) #TODO: Add paydate. #Oleg: I don't have an account with scheduled payment. # Need to wait for a while... return a
def account(self): label = u' '.join(u''.join(self.doc.xpath( u'//text()[contains(.,"Account ending in")]')).split()) balance = self.doc.xpath( '//span[@id="currentBalance"]/..')[0].text_content() a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD return a
def payments(self): for tr in self.doc.xpath('//tbody[@class="payment-summary"]' '//th[text()="Payment Summary"]/../../../tbody/tr'): method = tr.xpath('td[1]/text()')[0] amnode = tr.xpath('td[2]')[0] amsign = -1 if amnode.xpath('em') else 1 amount = amnode.text_content().strip() pmt = Payment() pmt.date = self.order_date() pmt.method = unicode(method) pmt.amount = amsign * AmTr.decimal_amount(amount) if pmt.method not in [u'Funds to be applied on backorder']: yield pmt
def account(self): label = u' '.join(u''.join( self.doc.xpath( u'//text()[contains(.,"Account ending in")]')).split()) balance = self.doc.xpath( '//span[@id="currentBalance"]/..')[0].text_content() a = Account() a.id = label[-4:] a.label = label a.currency = Account.get_currency(balance) a.balance = -AmTr.decimal_amount(balance) a.type = Account.TYPE_CARD return a
def iter_transactions(self): for li in self.doc.xpath('//section[@class="transactions"]//div/li'): date = li.xpath('p[@data-type="date"]//text()')[0].strip() label = li.xpath('p[@data-type="description"]//text()')[0].strip() amount = li.xpath('p[@data-type="amount"]//text()')[0].strip() t = Transaction() t.date = datetime.strptime(date, '%m/%d/%Y') t.rdate = datetime.strptime(date, '%m/%d/%Y') t.type = Transaction.TYPE_UNKNOWN t.raw = unicode(label) t.label = unicode(label) t.amount = -AmTr.decimal_amount(amount) yield t
def payments(self): for tr in self.doc.xpath( '//tbody[@class="payment-summary"]' '//th[text()="Payment Summary"]/../../../tbody/tr'): method = tr.xpath('td[1]/text()')[0] amnode = tr.xpath('td[2]')[0] amsign = -1 if amnode.xpath('em') else 1 amount = amnode.text_content().strip() pmt = Payment() pmt.date = self.order_date() pmt.method = unicode(method) pmt.amount = amsign * AmTr.decimal_amount(amount) yield pmt
def items(self): for span in self.doc.xpath('//div[@class="shipmentItems1"]' '/span[@class="item"]'): url = span.xpath('span[@class="itemLink"]/a/@href')[0] label = span.xpath('span[@class="itemLink"]/a/text()')[0] qty = span.xpath('span[@class="itemQuantity"]/text()')[0] price = span.xpath('span[@class="itemPrice"]/text()')[0] price = Decimal(qty)*AmTr.decimal_amount(price) item = Item() item.url = unicode(url) item.label = cleanup(label) item.price = price yield item
def items(self): for tr in self.doc.xpath('//tbody[@class="order-items"]/tr'): label = tr.xpath('*//h1')[0].text_content().strip() price = AmTr.decimal_amount( re.match(r'^\s*([^\s]+)(\s+.*)?', tr.xpath('*//div[@class="price"]')[0].text_content(), re.DOTALL).group(1)) url = 'http:' + tr.xpath('*//img/@src')[0] item = Item() item.label = unicode(label) item.url = unicode(url) item.price = price yield item
def iter_transactions(self): for ntrans in reversed(self.doc.xpath('//TRANSACTION')): desc = u' '.join(ntrans.xpath( 'TRANSDESCRIPTION/text()')[0].split()) tdate = u''.join(ntrans.xpath('TRANSACTIONDATE/text()')) pdate = u''.join(ntrans.xpath('POSTDATE/text()')) t = Transaction() t.date = datetime.strptime(tdate, '%m/%d/%Y') t.rdate = datetime.strptime(pdate or tdate, '%m/%d/%Y') t.type = Transaction.TYPE_UNKNOWN t.raw = desc t.label = desc t.amount = -AmTr.decimal_amount(ntrans.xpath('AMOUNT/text()')[0]) yield t
def get_account(self): name = self.account_name() balance = self.account_balance() currency = Account.get_currency(balance) id_ = self.account_id() type_ = self.account_type() paydate, paymin = self.account_paydatemin() cardlimit = self.account_cardlimit() account = Account() account.id = id_ account.label = name account.currency = currency account.balance = AmTr.decimal_amount(balance) account.type = type_ if paydate is not None: account.paydate = paydate if paymin is not None: account.paymin = paymin if cardlimit is not None: account.cardlimit = AmTr.decimal_amount(cardlimit) return account
def transactions(self): for tr in self.doc.xpath( u'//div[contains(b,"Credit Card transactions")]' u'/following-sibling::table[1]/tr'): label, date = tr.xpath('td[1]/text()')[0].strip().split(u'\xa0') amount = tr.xpath('td[2]/text()')[0].strip() date = datetime.strptime(date, '%B %d, %Y:') method = label.replace(u'ending in ', u'')[:-1].upper() amount = AmTr.decimal_amount(amount) pmt = Payment() pmt.date = date pmt.method = method pmt.amount = amount yield pmt
def iter_recent(self): records = json.loads(self.doc.xpath( '//div[@id="completedActivityRecords"]//input[1]/@value')[0]) recent = [x for x in records if x['PDF_LOC'] is None] for rec in sorted(recent, ActivityPage.cmp_records, reverse=True): desc = u' '.join(rec['TRANS_DESC'].split()) trans = Transaction((rec['REF_NUM'] or u'').strip()) trans.date = ActivityPage.parse_date(rec['TRANS_DATE']) trans.rdate = ActivityPage.parse_date(rec['POST_DATE']) trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = -AmTr.decimal_amount(rec['TRANS_AMOUNT']) yield trans
def get_account(self): name = self.account_name() balance = self.account_balance() currency = Account.get_currency(balance) id_ = self.account_id() type_ = self.account_type() account = Account() account.id = id_ account.label = name account.currency = currency account.balance = AmTr.decimal_amount(balance) account.type = type_ return account
def iter_transactions(self): for ntrans in reversed(self.doc.xpath('//TRANSACTION')): desc = u' '.join( ntrans.xpath('TRANSDESCRIPTION/text()')[0].split()) tdate = u''.join(ntrans.xpath('TRANSACTIONDATE/text()')) pdate = u''.join(ntrans.xpath('POSTDATE/text()')) t = Transaction() t.date = datetime.strptime(tdate, '%m/%d/%Y') t.rdate = datetime.strptime(pdate or tdate, '%m/%d/%Y') t.type = Transaction.TYPE_UNKNOWN t.raw = desc t.label = desc t.amount = -AmTr.decimal_amount(ntrans.xpath('AMOUNT/text()')[0]) yield t
def unsorted_trans(self): for jnl in self.doc["accountDetailsAndActivity"]["accountActivity"]["postedTransactionJournals"]: tdate = jnl["columns"][0]["activityColumn"][0] label = jnl["columns"][1]["activityColumn"][0] amount = jnl["columns"][3]["activityColumn"][0] xdescs = dict((x["label"], x["value"][0]) for x in jnl["extendedDescriptions"]) pdate = xdescs[u"Posted Date :"] ref = xdescs.get(u"Reference Number:") or u"" if amount.startswith(u"(") and amount.endswith(u")"): amount = AmTr.decimal_amount(amount[1:-1]) else: amount = -AmTr.decimal_amount(amount) label = clean_label(label) trans = Transaction(ref) trans.date = datetime.strptime(tdate, "%m-%d-%Y") trans.rdate = datetime.strptime(pdate, "%m-%d-%Y") trans.type = Transaction.TYPE_UNKNOWN trans.raw = label trans.label = label trans.amount = amount yield trans
def account_paydatemin(self): if self.doc.xpath(u'//p[contains(text(),' '"payment due date is not yet scheduled")]'): # If payment date is not scheduled yet, set it somewhere in a # distant future, so that we always have a valid date. return datetime.datetime.now() + datetime.timedelta(days=999), \ Decimal(0) else: date = self.doc.xpath(u'//span[contains(text(),"Minimum Payment")]' '/span/text()')[0] date = re.match(u'.*(../../..).*', date).group(1) date = datetime.datetime.strptime(date, '%m/%d/%y') amount = self.doc.xpath(u'//td[@headers="minimumPaymentDue"]' '//text()')[0].strip() return date, AmTr.decimal_amount(amount)
def iter_recent(self): records = json.loads( self.doc.xpath( '//div[@id="completedActivityRecords"]//input[1]/@value')[0]) recent = [x for x in records if x['PDF_LOC'] is None] for rec in sorted(recent, ActivityPage.cmp_records, reverse=True): desc = u' '.join(rec['TRANS_DESC'].split()) trans = Transaction((rec['REF_NUM'] or u'').strip()) trans.date = ActivityPage.parse_date(rec['TRANS_DATE']) trans.rdate = ActivityPage.parse_date(rec['POST_DATE']) trans.type = Transaction.TYPE_UNKNOWN trans.raw = desc trans.label = desc trans.amount = -AmTr.decimal_amount(rec['TRANS_AMOUNT']) yield trans
def parse(self): emonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] date_format, time_format, months = self.guess_format() for row in self.document.xpath('//table[@id="transactionTable"]/tbody/tr'): if len(row.xpath('.//td')) < 5: continue amount = row.xpath('.//td[@headers="gross"]')[-1].text_content().strip() if re.search('\d', amount): currency = Account.get_currency(amount) amount = AmTr.decimal_amount(amount) else: continue idtext = row.xpath('.//td[@class="detailsNoPrint"]//span[@class="accessAid"]')[0] \ .text_content().replace(u'\xa0', u' ').strip().rpartition(' ')[-1] trans = Transaction(idtext) trans.amount = amount trans._currency = currency datetext = row.xpath('.//td[@class="dateInfo"]')[0].text_content().strip() for i in range(0, 12): datetext = datetext.replace(months[i], emonths[i]) date = dateutil.parser.parse(datetext) trans.date = date trans.rdate = date trans.label = to_unicode(row.xpath('.//td[@class="emailInfo"]')[0].text_content().strip()) info = to_unicode(row.xpath('.//td[@class="paymentTypeInfo"]')[0].text_content().strip()) trans.raw = info + u' ' + trans.label if u'Authorization' in info or u'Autorisation' in info or \ u'Order' in info: continue if u'Credit Card' in trans.label or u'Carte bancaire' in trans.label: trans.type = Transaction.TYPE_CARD elif info.startswith(u'Payment') or info.startswith(u'Paiement'): trans.type = Transaction.TYPE_ORDER elif u'Currency Conversion' in info or u'Conversion de devise' in info: trans.type = Transaction.TYPE_BANK else: trans.type = Transaction.TYPE_UNKNOWN yield trans
def items(self): for tr in self.doc.xpath('//table[contains(@class,"items_table")]' '//tr[td[@class="items_desc"]]'): label = tr.xpath('*//div[@class="item_desc"]//span/text()')[0] url = tr.xpath('*//div[@class="item_img"]//@src')[0] onclk = tr.xpath('*//div[@class="item_img"]//@onclick') if onclk: url = re.match(r'window.open\(\'([^\']*)\'.*', onclk[0]).group(1) if url.startswith('/'): url = self.browser.BASEURL + url price = tr.xpath('td[@class="items_price"]/span/text()')[0] qty = tr.xpath('td[@class="items_qty"]//span/text()')[0] price = AmTr.decimal_amount(price) * Decimal(qty) item = Item() item.label = unicode(label) item.url = unicode(url) item.price = price yield item
def transactions(self): for row in self.doc.xpath('//span[contains(text(),"Transactions")]' '/../../div/div'): text = row.text_content().strip().replace('\n', ' ') if u'Items shipped:' not in text: continue date, method, amount = re.match( '.* ' '([A-z]+ [0-9]+, [0-9]+)' '[ -]+' '([A-z][^:]+)' ': +' '([^ ]+)', text).groups() date = datetime.strptime(date, '%B %d, %Y') method = method.replace(u'ending in ', u'').upper() amount = AmTr.decimal_amount(amount) pmt = Payment() pmt.date = date pmt.method = method pmt.amount = amount yield pmt
def iter_transactions(self): for ntrans in reversed(self.doc.xpath('//TRANSACTION')): desc = u' '.join(ntrans.xpath( 'TRANSDESCRIPTION/text()')[0].split()) tdate = u''.join(ntrans.xpath('TRANSACTIONDATE/text()')) pdate = u''.join(ntrans.xpath('POSTDATE/text()')) # Skip transactions which are not posted, # because they are not accounted for in balance calculation. if not pdate: continue t = Transaction() t.date = datetime.strptime(tdate, '%m/%d/%Y') t.rdate = datetime.strptime(pdate, '%m/%d/%Y') t.type = Transaction.TYPE_UNKNOWN t.raw = desc t.label = desc t.amount = -AmTr.decimal_amount(ntrans.xpath('AMOUNT/text()')[0]) yield t