<s> from __future__ import unicode_literals <EOL> import six <EOL> import toolz <EOL> import collections <EOL> from enum import Enum <EOL> from dateparser . date import DateDataParser <EOL> from . import schema <EOL> from . util import force_encode <EOL> class AccountType ( Enum ) : <EOL> CHECKING = '<STR_LIT>' <EOL> SAVINGS = '<STR_LIT>' <EOL> CREDIT_CARD = '<STR_LIT>' <EOL> CASH = '<STR_LIT>' <EOL> LINE_OF_CREDIT = '<STR_LIT>' <EOL> PAYPAL = '<STR_LIT>' <EOL> MERCHANT_ACCOUNT = '<STR_LIT>' <EOL> INVESTMENT_ACCOUNT = '<STR_LIT>' <EOL> MORTGAGE = '<STR_LIT>' <EOL> OTHER_ASSET = '<STR_LIT>' <EOL> OTHER_LIABILITY = '<STR_LIT>' <EOL> class CategoryType ( Enum ) : <EOL> OUTFLOW = '<STR_LIT>' <EOL> class TransactionStatus ( Enum ) : <EOL> CLEARED = '<STR_LIT>' <EOL> RECONCILED = '<STR_LIT>' <EOL> UNCLEARED = '<STR_LIT>' <EOL> class Model ( object ) : <EOL> _entity_type = None <EOL> def __init__ ( self , ynab , entity ) : <EOL> self . _ynab = ynab <EOL> self . _entity = entity <EOL> @ classmethod <EOL> @ toolz . curry <EOL> def _from_flat ( cls , ynab , data ) : <EOL> return cls ( ynab , cls . _entity_type ( data , strict = False ) ) <EOL> @ property <EOL> def id ( self ) : <EOL> return self . _entity . entityId <EOL> @ property <EOL> def is_valid ( self ) : <EOL> return not self . _entity . isTombstone <EOL> class Account ( Model ) : <EOL> _entity_type = schema . Account <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . name ) <EOL> @ property <EOL> def name ( self ) : <EOL> return self . _entity . accountName <EOL> @ property <EOL> def type ( self ) : <EOL> return AccountType ( self . _entity . accountType ) <EOL> @ property <EOL> def on_budget ( self ) : <EOL> return self . _entity . onBudget <EOL> @ property <EOL> def last_reconciled_date ( self ) : <EOL> return self . _entity . lastReconciledDate <EOL> @ property <EOL> def last_reconciled_balance ( self ) : <EOL> return self . _entity . lastReconciledBalance <EOL> @ property <EOL> def last_reconciled_check_number ( self ) : <EOL> return self . _entity . lastReconciledCheckNumber <EOL> @ property <EOL> def hidden ( self ) : <EOL> return self . _entity . hidden <EOL> @ property <EOL> def payees ( self ) : <EOL> return self . _ynab . payees . filter ( '<STR_LIT>' , self ) <EOL> @ property <EOL> def transactions ( self ) : <EOL> return self . _ynab . transactions . filter ( '<STR_LIT>' , self ) <EOL> @ property <EOL> def inbound_transactions ( self ) : <EOL> return self . _ynab . transactions . filter ( '<STR_LIT>' , self ) <EOL> @ property <EOL> def balance ( self ) : <EOL> return round ( sum ( self . transactions . amount ) , self . _ynab . precision ) <EOL> @ property <EOL> def cleared_balance ( self ) : <EOL> return round ( sum ( self . transactions . filter ( '<STR_LIT>' ) . amount ) , self . _ynab . precision ) <EOL> @ property <EOL> def reconciled_balance ( self ) : <EOL> return round ( sum ( self . transactions . filter ( '<STR_LIT>' ) . amount ) , self . _ynab . precision ) <EOL> @ property <EOL> def note ( self ) : <EOL> return self . _entity . note <EOL> class Payee ( Model ) : <EOL> _entity_type = schema . Payee <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . name ) <EOL> @ property <EOL> def name ( self ) : <EOL> return self . _entity . name <EOL> @ property <EOL> def target_account ( self ) : <EOL> return self . _ynab . accounts . by_id ( self . _entity . targetAccountId ) <EOL> @ property <EOL> def enabled ( self ) : <EOL> return self . _entity . enabled <EOL> @ property <EOL> def transactions ( self ) : <EOL> return self . _ynab . transactions . filter ( '<STR_LIT>' , self ) <EOL> class CategoryModel ( Model ) : <EOL> @ property <EOL> def name ( self ) : <EOL> return self . _entity . name <EOL> @ property <EOL> def type ( self ) : <EOL> return CategoryType ( self . _entity . type ) <EOL> class Category ( CategoryModel ) : <EOL> _entity_type = schema . SubCategory <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . full_name ) <EOL> @ property <EOL> def cached_balance ( self ) : <EOL> return self . _entity . cachedBalance <EOL> @ property <EOL> def master_category ( self ) : <EOL> return self . _ynab . master_categories . by_id ( self . _entity . masterCategoryId ) <EOL> @ property <EOL> def has_unresolved_conflicts ( self ) : <EOL> return not self . _entity . isResolvedConflict <EOL> @ property <EOL> def note ( self ) : <EOL> return self . _entity . note <EOL> @ property <EOL> def full_name ( self ) : <EOL> return '<STR_LIT>' . format ( self . master_category . name , self . name ) <EOL> @ property <EOL> def transactions ( self ) : <EOL> return self . _ynab . transactions . filter ( '<STR_LIT>' , self ) <EOL> class MasterCategory ( CategoryModel ) : <EOL> _entity_type = schema . MasterCategory <EOL> def __init__ ( self , ynab , entity ) : <EOL> super ( MasterCategory , self ) . __init__ ( ynab , entity ) <EOL> self . _categories = Categories ( <EOL> Category ( ynab , category ) for category in self . _entity . subCategories or [ ] ) <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . name ) <EOL> @ property <EOL> def categories ( self ) : <EOL> return self . _categories <EOL> def __iter__ ( self ) : <EOL> return iter ( self . _categories ) <EOL> class TransactionModel ( Model ) : <EOL> @ property <EOL> def memo ( self ) : <EOL> return self . _entity . memo <EOL> @ property <EOL> def amount ( self ) : <EOL> return round ( float ( self . _entity . amount or <NUM_LIT:0.> ) , self . _ynab . precision ) <EOL> @ property <EOL> def category ( self ) : <EOL> return self . _ynab . categories . by_id ( self . _entity . categoryId ) <EOL> @ property <EOL> def target_account ( self ) : <EOL> return self . _ynab . accounts . by_id ( self . _entity . targetAccountId ) <EOL> @ property <EOL> def transfer_transaction ( self ) : <EOL> return self . _ynab . transactions . by_id ( self . _entity . transferTransactionId ) <EOL> @ property <EOL> def has_unresolved_conflicts ( self ) : <EOL> return not self . _entity . isResolvedConflict <EOL> class SubTransaction ( TransactionModel ) : <EOL> _entity_type = schema . SubTransaction <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( <EOL> self . amount , self . category . name if self . category else '<STR_LIT>' ) <EOL> @ property <EOL> def parent ( self ) : <EOL> return self . _ynab . transactions . by_id ( self . _entity . parentTransactionId ) <EOL> class Transaction ( TransactionModel ) : <EOL> _entity_type = schema . Transaction <EOL> def __init__ ( self , ynab , entity ) : <EOL> super ( Transaction , self ) . __init__ ( ynab , entity ) <EOL> self . _sub_transactions = SubTransactions ( <EOL> SubTransaction ( ynab , t ) for t in self . _entity . subTransactions or [ ] ) <EOL> @ force_encode <EOL> def __repr__ ( self ) : <EOL> info = '<STR_LIT>' <EOL> if self . category : <EOL> info += '<STR_LIT>' . format ( self . category . name ) <EOL> if self . payee : <EOL> info += '<STR_LIT>' . format ( self . payee . name ) <EOL> return '<STR_LIT>' . format ( <EOL> self . date or '<STR_LIT>' , self . account . name if self . account else '<STR_LIT>' , <EOL> self . amount , info ) <EOL> @ property <EOL> def date ( self ) : <EOL> return self . _entity . date <EOL> @ property <EOL> def status ( self ) : <EOL> return TransactionStatus ( self . _entity . cleared ) <EOL> @ property <EOL> def cleared ( self ) : <EOL> return self . status in ( TransactionStatus . CLEARED , TransactionStatus . RECONCILED ) <EOL> @ property <EOL> def reconciled ( self ) : <EOL> return self . status == TransactionStatus . RECONCILED <EOL> @ property <EOL> def accepted ( self ) : <EOL> return self . _entity . accepted <EOL> @ property <EOL> def account ( self ) : <EOL> return self . _ynab . accounts . by_id ( self . _entity . accountId ) <EOL> @ property <EOL> def payee ( self ) : <EOL> return self . _ynab . payees . by_id ( self . _entity . payeeId ) <EOL> @ property <EOL> def date_entered_from_schedule ( self ) : <EOL> return self . _entity . dateEnteredFromSchedule <EOL> @ property <EOL> def sub_transactions ( self ) : <EOL> return self . _sub_transactions <EOL> class ModelCollection ( collections . Sequence ) : <EOL> _model_type = None <EOL> _index_key = None <EOL> _NO_VALUE = object ( ) <EOL> def __init__ ( self , elements ) : <EOL> self . _elements = list ( e for e in elements if e . is_valid ) <EOL> self . _index = { element . id : element for element in self . _elements } <EOL> @ classmethod <EOL> @ toolz . curry <EOL> def _from_flat ( cls , ynab , data ) : <EOL> return cls ( map ( cls . _model_type . _from_flat ( ynab ) , data ) ) <EOL> def __len__ ( self ) : <EOL> return len ( self . _elements ) <EOL> def __getitem__ ( self , key ) : <EOL> if isinstance ( key , six . string_types ) : <EOL> if self . _index_key is not None : <EOL> for element in self : <EOL> if getattr ( element , self . _index_key ) == key : <EOL> return element <EOL> raise KeyError ( key ) <EOL> else : <EOL> return self . _elements [ key ] <EOL> def __getattr__ ( self , key ) : <EOL> return [ getattr ( element , key ) for element in self ] <EOL> def __repr__ ( self ) : <EOL> return repr ( list ( self ) ) <EOL> def __str__ ( self ) : <EOL> return str ( list ( self ) ) <EOL> def by_id ( self , id ) : <EOL> """<STR_LIT>""" <EOL> return self . _index . get ( id , None ) <EOL> def sort_by ( self , field ) : <EOL> """<STR_LIT>""" <EOL> self . _elements = sorted ( self . _elements , key = lambda element : getattr ( element , field ) ) <EOL> def filter ( self , field , value = _NO_VALUE ) : <EOL> """<STR_LIT>""" <EOL> return type ( self ) ( element for element in self <EOL> if ( value is not self . _NO_VALUE and getattr ( element , field ) == value ) or <EOL> ( value is self . _NO_VALUE and getattr ( element , field ) ) ) <EOL> class Accounts ( ModelCollection ) : <EOL> _model_type = Account <EOL> _index_key = '<STR_LIT:name>' <EOL> class Payees ( ModelCollection ) : <EOL> _model_type = Payee <EOL> _index_key = '<STR_LIT:name>' <EOL> class MasterCategories ( ModelCollection ) : <EOL> _model_type = MasterCategory <EOL> _index_key = '<STR_LIT:name>' <EOL> class Categories ( ModelCollection ) : <EOL> _model_type = Category <EOL> _index_key = '<STR_LIT>' <EOL> class Transactions ( ModelCollection ) : <EOL> _model_type = Transaction <EOL> @ property <EOL> def amount ( self ) : <EOL> amount = [ t . amount for t in self ] <EOL> try : <EOL> import numpy as np <EOL> return np . round ( np . array ( amount , dtype = np . float64 ) , self . _ynab . precision ) <EOL> except ImportError : <EOL> return amount <EOL> def _parse_date ( self , string ) : <EOL> parser = DateDataParser ( ) <EOL> date = parser . get_date_data ( string ) [ '<STR_LIT>' ] <EOL> if date is None : <EOL> raise RuntimeError ( '<STR_LIT>' . format ( string ) ) <EOL> return date . date ( ) <EOL> def between ( self , start = None , end = None ) : <EOL> """<STR_LIT>""" <EOL> transactions = list ( self ) <EOL> if start is not None : <EOL> transactions = [ t for t in transactions if t . date >= self . _parse_date ( start ) ] <EOL> if end is not None : <EOL> transactions = [ t for t in transactions if t . date <= self . _parse_date ( end ) ] <EOL> return type ( self ) ( transactions ) <EOL> def since ( self , date ) : <EOL> """<STR_LIT>""" <EOL> return self . between ( start = date ) <EOL> def till ( self , date ) : <EOL> """<STR_LIT>""" <EOL> return self . between ( end = date ) <EOL> class SubTransactions ( ModelCollection ) : <EOL> _model_type = SubTransaction <EOL> class BudgetMetaData ( Model ) : <EOL> _entity_type = schema . BudgetMetaData <EOL> _PRECISIONS = { <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:3> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> } <EOL> @ property <EOL> def is_valid ( self ) : <EOL> return True <EOL> @ property <EOL> def currency_locale ( self ) : <EOL> return self . _entity . currencyLocale <EOL> @ property <EOL> def date_locale ( self ) : <EOL> return self . _entity . dateLocale <EOL> @ property <EOL> def budget_type ( self ) : <EOL> return self . _entity . budgetType <EOL> @ property <EOL> def is_strict ( self ) : <EOL> return self . _entity . strictBudget <EOL> @ property <EOL> def precision ( self ) : <EOL> return self . _PRECISIONS . get ( self . currency_locale , <NUM_LIT:2> ) <EOL> class FileMetaData ( Model ) : <EOL> _entity_type = schema . FileMetaData <EOL> @ property <EOL> def current_knowledge ( self ) : <EOL> return self . _entity . currentKnowledge <EOL> @ property <EOL> def id ( self ) : <EOL> return None <EOL> @ property <EOL> def is_valid ( self ) : <EOL> return True </s>
