Esempio n. 1
0
    def delete(self):
        model = self.get_sa_model()
        db = self.get_sa_session()

        result = {}
        for id in request.params.getall('id'):
            try:
                if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, id):
                    result[id] = {
                        "deleted": False,
                        "message": Messages.permissionDenied()
                    }
                    continue
                item = db.query(model.Balance).filter_by(uid=id).one()
            except InvalidRequestError:
                result[id] = {
                    "deleted" : False,
                    "message": Messages.elementNotFound(key=id)
                }
                continue

            try:
                db.delete(item)
                db.commit()
                result[item.uid] = {
                    "deleted" : True,
                }
            except Exception, e:
                result[item.uid] = {
                    "deleted" : False,
                    "message" : Messages.failedToDelete(exception=e)
                }
Esempio n. 2
0
    def delete(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        result = {}
        for id in request.params.getall('id'):
            try:
                item = db.query(model.BalanceChange).filter_by(uid=id).filter_by(balance_uid=balance_uid).one()
            except InvalidRequestError:
                result[id] = {
                    "deleted" : False,
                    "message": Messages.elementNotFound(key=id)
                }
                continue

            else:
                try:
                    Operations(db, model).delete_balance_change(item)
                    result[item.uid] = {
                        "deleted" : True,
                    }
                except Exception, e:
                    result[item.uid] = {
                        "deleted" : False,
                        "message" : Messages.failedToDelete(exception=e),
                    }
Esempio n. 3
0
    def category(self):
        dbFacade = self.dbFacade()
        result = {}
            
        category = dbFacade.balances.categoryDao.find_by_name(request.params.get('category'))
        if category is None:
            return { "failure": Messages.invalidArguments() }

        for id in request.params.getall('id'):
            try:
                item = dbFacade.balances.changeDao.find_by_uid(id, options=[eagerload('balance')])
                if item is None:
                    result[id] = {
                        "deleted" : False,
                        "message": Messages.elementNotFound(key=id)
                    }
                    continue

                if not item.balance or not item.balance.can_modify_balance(h.authenticated_user().uid):
                    result[id] = {
                        "deleted" : False,
                        "message": Messages.permissionDenied()
                    }
                    continue

                item.category = category.name
                
                dbFacade.db.commit()
                result[id] = { "modified" : True }
            except Exception, e:
                result[id] = {
                    "deleted" : False,
                    "message" : Messages.failedToDelete(exception=e),
                }
Esempio n. 4
0
    def list_tags(self, id):
        dbFacade = DbFacade(request.environ["sqlalchemy.session"], request.environ["sqlalchemy.model"])

        balance = dbFacade.balances.balanceDao.find_by_uid(id)
        if not balance or not balance.can_modify_balance(h.authenticated_user().uid):
            return {"failure": Messages.permissionDenied()}

        query = request.params.get("query", None)
        if query:
            tags = balance.get_tags_starting_with(query)
        else:
            tags = balance.tags.order_by(dbFacade.model.BalanceTag.tag).all()

        total = len(tags)
        try:
            page_nr = int(request.params["page_nr"])
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params["items_per_page"])
        except:
            items_per_page = 15

        subset = Page(tags, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return {
            "totalItems": total,
            "itemsFound": len(subset),
            "items": [{"uid": item.uid, "tag": item.tag} for item in subset],
        }
Esempio n. 5
0
    def delete(self):
        dbFacade = self.dbFacade()

        result = {}
        for id in request.params.getall('id'):
            try:
                item = dbFacade.balances.balanceDao.find_by_uid(id)
                if not item or not item.can_modify_balance(h.authenticated_user().uid):
                    result[id] = {
                        "deleted": False,
                        "message": Messages.permissionDenied()
                    }
                    continue
            except InvalidRequestError:
                result[id] = {
                    "deleted" : False,
                    "message": Messages.elementNotFound(key=id)
                }
                continue

            try:
                dbFacade.db.delete(item)
                dbFacade.db.commit()
                result[item.uid] = {
                    "deleted" : True,
                }
            except Exception, e:
                result[item.uid] = {
                    "deleted" : False,
                    "message" : Messages.failedToDelete(exception=e)
                }
Esempio n. 6
0
    def delete(self):
        result = {}
        for id in request.params.getall('id'):
            try:
                item = self.dbFacade().balances.changeDao.find_by_uid(id, options=[eagerload('balance'), eagerload('transfer')])
                if item is None:
                    result[id] = {
                        "deleted" : False,
                        "message": Messages.elementNotFound(key=id)
                    }
                    continue

                if not item.balance or not item.balance.can_modify_balance(h.authenticated_user().uid) \
                    or (item.transfer and not item.transfer.balance) \
                    or (item.transfer and not item.transfer.balance.can_modify_balance(h.authenticated_user().uid)):
                    result[id] = {
                        "deleted" : False,
                        "message": Messages.permissionDenied()
                    }
                    continue
                
                if item.transfer:
                    self.dbFacade().db.delete(item.transfer)
                self.dbFacade().db.delete(item)
                self.dbFacade().db.commit()
                result[id] = { "deleted" : True }
            except Exception, e:
                result[id] = {
                    "deleted" : False,
                    "message" : Messages.failedToDelete(exception=e),
                }
Esempio n. 7
0
    def _by_day(self, balance_uid, is_income):
        db = request.environ['sqlalchemy.session']
        model = request.environ['sqlalchemy.model']

        balance = db.query(model.Balance).filter_by(uid = balance_uid).first()
        if not balance or not balance.can_see_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        conditions = [model.BalanceChange.c.balance_uid == balance_uid, model.BalanceChange.c.is_income == is_income]

        (start_date, end_date) = self._get_dates()
        if start_date:
            conditions.append(model.BalanceChange.c.occurred_on >= start_date)

        if end_date:
            conditions.append(model.BalanceChange.c.occurred_on <= end_date)

        dates = db.execute(select([func.sum(model.BalanceChange.c.amount).label('summary'), model.BalanceChange.c.occurred_on.label('date')],
            and_(*conditions),
            from_obj=[model.balance_changes_table], order_by=['date'], group_by=['date'])).fetchall()

        return { 
            "totalItems" : len(dates),
            "itemsFound": len(dates),
            "items" : [{ 
                "date" : item.date, 
                "summary": item.summary} for item in dates ]
        }
Esempio n. 8
0
    def _list_by_category(self, balance_uid, expenses = True, incomes = True):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        try:
            user_uid = h.authenticated_user().uid
        except:
            return { "failure": Messages.pemissionDenied() }
        if not Operations(db, model).can_see_balance(user_uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        now = date.today()
       
        select_expenses = select(
            [model.ExpenseCategory.c.uid.label('uid'), model.ExpenseCategory.c.name.label('name'), func.sum(model.BalanceChange.c.amount).label('summary')], 
            and_(model.BalanceChange.is_income==False,
                model.ExpenseCategory.uid==model.BalanceChange.expense_category_uid,
                model.BalanceChange.balance_uid==balance_uid,
                model.BalanceChange.occurred_on >= date(now.year, now.month, 1)), 
            from_obj=[model.expense_categories_table, model.balance_changes_table],
            group_by=[model.ExpenseCategory.c.uid, model.ExpenseCategory.c.name])

        select_incomes = select(
            [model.IncomeCategory.c.uid.label('uid'), model.IncomeCategory.c.name.label('name'), func.sum(model.BalanceChange.c.amount).label('summary')], 
            and_(model.BalanceChange.is_income==True,
                model.IncomeCategory.uid==model.BalanceChange.income_category_uid,
                model.BalanceChange.balance_uid==balance_uid,
                model.BalanceChange.occurred_on >= date(now.year, now.month, 1)), 
            from_obj=[model.income_categories_table, model.balance_changes_table],
            group_by=[model.IncomeCategory.c.uid, model.IncomeCategory.c.name])

        if expenses and incomes:
            query = union(select_expenses, select_incomes)
        else:
            query = expenses and select_expenses or select_incomes

        balance_changes = db.execute(query.order_by('name')).fetchall()
        total = len(balance_changes)
        try:
            page_nr = request.params['page_nr']
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params['items_per_page'])
        except:
            items_per_page = 15
        
        subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid,
                "name" : item.name,
                "summary" : h.format_decimal(Decimal(item.summary))} for item in subset ]
        }
Esempio n. 9
0
    def list(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        balance = db.query(model.Balance).filter_by(uid = balance_uid).first()
        if not balance or not balance.can_see_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        qr = balance.changes \
            .options(eagerload('expense_category'), eagerload('income_category'), eagerload('tags')) \
            .order_by(model.BalanceChange.occurred_on)

        (start_date, end_date) = self._get_dates()

        if start_date:
            qr = qr.filter(model.BalanceChange.occurred_on >= start_date)

        if end_date:
            qr = qr.filter(model.BalanceChange.occurred_on <= end_date)

        balance_changes = qr.all()

        total = len(balance_changes)
        try:
            page_nr = int(request.params['page_nr'])
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params['items_per_page'])
        except:
            items_per_page = 15
        
        subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return {
            "summary" : {
                "total" : self._total(balance_uid),
                "date_range" : {
                    "expenses" : self._expenses_for_date_range(balance_uid, start_date, end_date),
                    "incomes" : self._incomes_for_date_range(balance_uid, start_date, end_date),
                },
            },
            "changes": { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid, 
                "category_uid" : item.is_income and item.income_category_uid or item.expense_category_uid, 
                "category" : (item.is_income and item.income_category or item.expense_category).name, 
                "amount" : Decimal(item.amount), 
                "description" : item.description, 
                "occurred_on": str(item.occurred_on), 
                "is_income": item.is_income,
                "tags_as_string": item.tags_as_string()} for item in subset ]
            }
        }
Esempio n. 10
0
    def edit(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        balance = db.query(model.Balance).filter_by(uid = balance_uid).first()
        if not balance or not balance.can_modify_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        uid = int(request.params['uid'])
        bc = balance.changes.filter_by(uid=uid).first()
        if not bc:
            abort(404)

        try:
             with localcontext() as ctx:
                ctx.prec = 2
                bc.amount = h.parse_decimal(request.params['amount'])
        except:
            log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1)
            pass

        try:
            if int(request.params['is_income']) >= 0:
                bc.income_category_uid = int(request.params['income_category_uid'])
                bc.expense_category_uid = None
                bc.is_income = True
            else:
                bc.expense_category_uid = int(request.params['expense_category_uid'])
                bc.income_category_uid = None
                bc.is_income = False
        except:
            pass

        try:
            bc.description = request.params['description']
        except:
            pass

        try:
            bc.occurred_on = h.parse_date(request.params['occurred_on'])
        except:
            log.error("Invalid date: %s" % request.params.get('occurred_on'), exc_info=1)
            pass

        ops = Operations(db, model)
        try:
            ops.change_tags_from_string(bc, request.params['tags'])
        except:
            pass

        ops.save_balance_change(bc)
        return { "id" : bc.uid }
Esempio n. 11
0
    def add(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        try:
            with localcontext() as ctx:
                ctx.prec = 2
            	try:
                	amount = h.parse_decimal(request.params['amount'])
            	except NumberFormatError:
                	return { "failure": Messages.invalidCurrencyFormat() }
            expense_date = parser.parse(request.params['occurred_on']) 
            income_category_uid = None
            expense_category_uid = None

            if (int(request.params['is_income']) >= 0):
                    income_category_uid = int(request.params['income_category_uid'])
                    is_income = True
            else:
                    expense_category_uid = int(request.params['expense_category_uid'])
                    is_income = False
        except:
            return { "failure": Messages.invalidArguments() }

        tags = request.params.get('tags', '')
    
        try:
            description = request.params['description']
        except:
            description = ""

        try:
            bc = model.BalanceChange(
                amount = amount, 
                description = description, 
                balance_uid = balance_uid, 
                user_uid = h.authenticated_user().uid, 
                expense_category_uid = expense_category_uid,
                occurred_on = expense_date,
                is_income = is_income,
                income_category_uid = income_category_uid
            )
            ops = Operations(db, model)
            ops.change_tags_from_string(bc, tags)
            ops.save_balance_change(bc)
        except IntegrityError, e:
            return { "failure": Messages.primaryKeyViolation() }
Esempio n. 12
0
    def add(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        balance = db.query(model.Balance).filter_by(uid = balance_uid).first()
        if not balance or not balance.can_modify_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        try:
            with localcontext() as ctx:
                ctx.prec = 2
                try:
                    amount = h.parse_decimal(request.params['amount'])
                except:
                    log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1)
                    return { "failure": Messages.invalidCurrencyFormat() }
            expense_date = h.parse_date(request.params['occurred_on']) 
            income_category_uid = None
            expense_category_uid = None

            if (int(request.params['is_income']) >= 0):
                    income_category_uid = int(request.params['income_category_uid'])
                    is_income = True
            else:
                    expense_category_uid = int(request.params['expense_category_uid'])
                    is_income = False
        except:
            log.error("Failed to parse arguments %s" % str(request.params), exc_info=1)
            return { "failure": Messages.invalidArguments() }

        tags = request.params.get('tags', '')
        description = request.params.get('description', '')

        bc = model.BalanceChange(
            amount = amount, 
            description = description,
            user_uid = h.authenticated_user().uid, 
            expense_category_uid = expense_category_uid,
            occurred_on = expense_date,
            is_income = is_income,
            income_category_uid = income_category_uid
        )

        balance.changes.append(bc)
        db.flush()
        ops = Operations(db, model)
        ops.change_tags_from_string(bc, tags)
        ops.save_balance_change(bc)

        return { "id" : bc.uid }
Esempio n. 13
0
    def edit(self, balance_uid):
        dbFacade = DbFacade(request.environ['sqlalchemy.session'], request.environ['sqlalchemy.model'])

        balance = dbFacade.balances.balanceDao.find_by_uid(balance_uid)
        if not balance or not balance.can_modify_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        uid = int(request.params['uid'])
        bc = balance.changes.filter_by(uid=uid).first()
        if not bc:
            abort(404)

        try:
             with localcontext() as ctx:
                ctx.prec = 2
                bc.amount = h.parse_decimal(request.params['amount'])
        except:
            log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1)
            pass

        try:
            if int(request.params['is_income']) >= 0:
                bc.income_category_uid = int(request.params['income_category_uid'])
                bc.expense_category_uid = None
                bc.is_income = True
            else:
                bc.expense_category_uid = int(request.params['expense_category_uid'])
                bc.income_category_uid = None
                bc.is_income = False
        except:
            pass

        try:
            bc.description = request.params['description']
        except:
            pass

        try:
            bc.occurred_on = h.parse_date(request.params['occurred_on'])
        except:
            log.error("Invalid date: %s" % request.params.get('occurred_on'), exc_info=1)
            pass

        bc.tags = dbFacade.balances.find_or_create_tags(balance, 
            dbFacade.balances.elements_from_string(request.params.get('tags', '')))

        dbFacade.balances.changeDao.save(bc)
        dbFacade.db.commit()
        return { "id" : bc.uid }
Esempio n. 14
0
    def add(self, balance_uid):
        dbFacade = DbFacade(request.environ['sqlalchemy.session'], request.environ['sqlalchemy.model'])

        balance = dbFacade.balances.balanceDao.find_by_uid(balance_uid)
        if not balance or not balance.can_modify_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        try:
            with localcontext() as ctx:
                ctx.prec = 2
                try:
                    amount = h.parse_decimal(request.params['amount'])
                except:
                    log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1)
                    return { "failure": Messages.invalidCurrencyFormat() }
            expense_date = h.parse_date(request.params['occurred_on']) 
            income_category_uid = None
            expense_category_uid = None

            if (int(request.params['is_income']) >= 0):
                    income_category_uid = int(request.params['income_category_uid'])
                    is_income = True
            else:
                    expense_category_uid = int(request.params['expense_category_uid'])
                    is_income = False
        except:
            log.error("Failed to parse arguments %s" % str(request.params), exc_info=1)
            return { "failure": Messages.invalidArguments() }

        tags = request.params.get('tags', '')
        description = request.params.get('description', '')

        bc = dbFacade.model.BalanceChange(
            amount = amount, 
            description = description,
            user_uid = h.authenticated_user().uid, 
            expense_category_uid = expense_category_uid,
            occurred_on = expense_date,
            is_income = is_income,
            income_category_uid = income_category_uid
        )
        
        bc.tags = dbFacade.balances.find_or_create_tags(balance, 
            dbFacade.balances.elements_from_string(tags))

        dbFacade.balances.add_balance_change(balance, bc)
        dbFacade.db.commit()
        return { "id" : bc.uid }
Esempio n. 15
0
    def edit(self):
        model = request.environ["sqlalchemy.model"]
        db = request.environ["sqlalchemy.session"]

        uid = int(request.params["uid"])
        if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, uid):
            return {"failure": Messages.permissionDenied()}

        balance = db.query(model.Balance).filter_by(uid=uid).one()
        try:
            balance.name = request.params["name"]
        except:
            pass
        db.commit()

        return {"id": balance.uid}
Esempio n. 16
0
    def edit(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        if not Operations(db, model).can_modify_balance(h.authenticated_user().uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        uid = int(request.params['uid'])
        bc = db.query(model.BalanceChange).filter_by(uid=uid).filter_by(balance_uid=balance_uid).one()
        try:
             with localcontext() as ctx:
                ctx.prec = 2
                bc.amount = h.parse_decimal(request.params['amount'])
        except:
            pass

        try:
            if int(request.params['is_income']) >= 0:
                bc.income_category_uid = int(request.params['income_category_uid'])
                bc.expense_category_uid = None
                bc.is_income = True
            else:
                bc.expense_category_uid = int(request.params['expense_category_uid'])
                bc.income_category_uid = None
                bc.is_income = False
        except:
            pass

        try:
            bc.description = request.params['description']
        except:
            pass

        try:
            bc.occurred_on = parser.parse(request.params['occurred_on'])
        except:
            pass

        ops = Operations(db, model)
        try:
            ops.change_tags_from_string(bc, request.params['tags'])
        except:
            pass

        ops.save_balance_change(bc)
        return { "id" : bc.uid }
Esempio n. 17
0
    def _edit_balance(self, balance):
        if balance.uid is not None:
            if not balance.can_modify_balance(h.authenticated_user().uid):
                return { "failure": Messages.permissionDenied() }

        try:
            balance.name = request.params['name'][0:25]
        except:
            return { "failure": Messages.invalidArguments() }

        if len(balance.users.all()) == 0:
            user_balance = self.dbFacade().model.UserBalance(user_uid=h.authenticated_user().uid, writable=True)
            balance.users.append(user_balance)
            h.authenticated_user().balances.append(user_balance)

        self.dbFacade().balances.balanceDao.save(balance)
        self.dbFacade().db.commit()

        return { "id" : balance.uid }
Esempio n. 18
0
    def report(self, balance_uid):
        dbFacade = self.dbFacade()

        if "all" == balance_uid:
            balance_uids = [userBalance.balance_uid for userBalance in h.authenticated_user().balances]
        else:
            balance = dbFacade.balances.balanceDao.find_by_uid(balance_uid)
            if not balance or not balance.can_see_balance(h.authenticated_user().uid):
                return { "failure": Messages.permissionDenied() }
            balance_uids = [balance.uid]

        return { 
            "expenses": { 
                "by_category": self._ops_by_category(balance_uids, expenses=True),
                "by_tags": self._ops_by_tags(balance_uids, expenses=True),
            }, 
            "incomes": {    
                "by_category": self._ops_by_category(balance_uids, incomes=True),
                "by_tags": self._ops_by_tags(balance_uids, incomes=True),
            },
        }
Esempio n. 19
0
    def list(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        try:
            user_uid = h.authenticated_user().uid
        except:
            return { "failure": Messages.pemissionDenied() }
        if not Operations(db, model).can_see_balance(user_uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        balance_changes = db.query(model.BalanceChange) \
            .options(eagerload('expense_category'), eagerload('income_category')) \
            .filter_by(balance_uid = balance_uid).order_by(model.BalanceChange.occurred_on).all()
        total = len(balance_changes)
        try:
            page_nr = request.params['page_nr']
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params['items_per_page'])
        except:
            items_per_page = 15
        
        subset = Page(balance_changes, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid, 
                "category_uid" : item.is_income and item.income_category_uid or item.expense_category_uid, 
                "category" : (item.is_income and item.income_category or item.expense_category).name, 
                "amount" : h.format_decimal(Decimal(item.amount)), 
                "description" : item.description, 
                "occurred_on": str(item.occurred_on), 
                "is_income": item.is_income,
                "tags_as_string": item.tags_as_string()} for item in subset ]
        }
Esempio n. 20
0
    def _list_by_category(self, balance_uid, query):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        balance = db.query(model.Balance).filter_by(uid = balance_uid).first()
        if not balance or not balance.can_see_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        balance_changes = db.execute(query.order_by('name')).fetchall()
        total = len(balance_changes)

        items_per_page = request.params.get('items_per_page')
        if items_per_page:
            balance_changes = Page(balance_changes, item_count=total, current_page=int(request.params.get('page_nr')), items_per_page=int(items_per_page))
        
        return { 
            "totalItems" : total,
            "itemsFound" : len(balance_changes),
            "items" : [{ 
                "uid" : item.uid,
                "name" : item.name,
                "summary" : Decimal(item.summary)} for item in balance_changes ]
        }
Esempio n. 21
0
    def list_tags(self, id):
        model = request.environ["sqlalchemy.model"]
        db = request.environ["sqlalchemy.session"]

        try:
            user_uid = h.authenticated_user().uid
        except:
            return { "failure": Messages.pemissionDenied() }
        if not Operations(db, model).can_see_balance(user_uid, id):
            return { "failure": Messages.permissionDenied() }

        try:
            query = request.params['query']
        except:
            query = ""

        tags = db.query(model.BalanceTag) \
            .filter_by(balance_uid = id).order_by(model.BalanceTag.tag).all()
        total = len(tags)
        try:
            page_nr = int(request.params['page_nr'])
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params['items_per_page'])
        except:
            items_per_page = 15
        
        subset = Page(tags, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid, 
                "tag": item.tag } for item in subset if item.tag.startswith(query)]
        }
Esempio n. 22
0
    def list_months(self, balance_uid):
        model = request.environ['sqlalchemy.model']
        db = request.environ['sqlalchemy.session']

        try:
            user_uid = h.authenticated_user().uid
        except:
            return { "failure": Messages.invalidArguments() }
        if not Operations(db, model).can_see_balance(user_uid, balance_uid):
            return { "failure": Messages.permissionDenied() }

        months = db.execute(
            select(
                [extract('year', model.BalanceChange.c.occurred_on).label('year'), extract('month', model.BalanceChange.c.occurred_on).label('month')], 
                model.BalanceChange.c.balance_uid==balance_uid,
                from_obj=[model.balance_changes_table],
                group_by=[extract('year', model.BalanceChange.c.occurred_on), extract('month', model.BalanceChange.c.occurred_on)])).fetchall()

        total = len(months)
        try:
            page_nr = request.params['page_nr']
        except:
            page_nr = 1

        try:
            items_per_page = int(request.params['items_per_page'])
        except:
            items_per_page = 15
        
        subset = Page(months, item_count=total, current_page=page_nr, items_per_page=items_per_page)
        return { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "year" : int(item.year), 
                "month": int(item.month) } for item in subset ]
        }
Esempio n. 23
0
    def _edit_change(self, to_bc):
        dbFacade = self.dbFacade()
    
        if to_bc.uid is not None:
            if not to_bc.balance or not to_bc.balance.can_modify_balance(h.authenticated_user().uid):
                return { "failure": Messages.permissionDenied() }

            # If it's a transfer check if user can modify the other balance
            if to_bc.transfer:
                old_from_balance = dbFacade.balances.balanceDao.find_by_uid(to_bc.transfer.balance_uid)
                if not old_from_balance or not old_from_balance.can_modify_balance(h.authenticated_user().uid):
                    return { "failure": Messages.permissionDenied() }

        to_balance_uid = request.params.get('to_balance_uid')
        to_balance = dbFacade.balances.balanceDao.find_by_uid(to_balance_uid)
        if not to_balance or not to_balance.can_modify_balance(h.authenticated_user().uid):
            return { "failure": Messages.permissionDenied() }

        try:
             with localcontext() as ctx:
                ctx.prec = 2
                to_bc.amount = h.parse_decimal(request.params['amount'])
        except:
            log.error("Invalid number: %s" % request.params.get('amount'), exc_info=1)
            return { "failure": Messages.invalidCurrencyFormat() }
    
        try:
            to_bc.occurred_on = h.parse_date(request.params['occurred_on']) 
        except:
            return { "failure": Messages.invalidDate() }
            
        try:
            to_bc.change_category_uid = int(request.params['change_category_uid'])
        except:
            log.error("Failed to parse arguments %s" % str(request.params), exc_info=1)
            return { "failure": Messages.invalidArguments() }

        to_bc.balance = to_balance
        to_bc.tags = [dbFacade.model.ChangeTag(tag=tag) for tag in dbFacade.balances.elements_from_string(request.params.get('tags', ''))]
        to_bc.description = request.params.get('description', '')
        to_bc.user_uid = h.authenticated_user().uid

        from_balance_uid = request.params.get('from_balance_uid')
        if from_balance_uid is not None:
            if from_balance_uid == to_balance_uid:
                return { "failure": Messages.pleaseSelectDifferentAccounts() }

            from_balance = dbFacade.balances.balanceDao.find_by_uid(from_balance_uid)
            if not from_balance or not from_balance.can_modify_balance(h.authenticated_user().uid):
                return { "failure": Messages.permissionDenied() }

            from_bc = to_bc.transfer and to_bc.transfer or dbFacade.model.BalanceChange()
            to_bc.amount = abs(to_bc.amount)
            from_bc.amount = -to_bc.amount
            from_bc.occurred_on = to_bc.occurred_on
            from_bc.change_category_uid = to_bc.change_category_uid
            from_bc.balance = from_balance
            from_bc.tags = [dbFacade.model.ChangeTag(tag=tag) for tag in dbFacade.balances.elements_from_string(request.params.get('tags', ''))] 
            from_bc.description = to_bc.description
            from_bc.user_uid = h.authenticated_user().uid

            from_bc.transfer = to_bc
            to_bc.transfer = from_bc
        elif to_bc.transfer is not None:
            from_bc = to_bc.transfer
            from_bc.transfer = None
            to_bc.transfer = None
            dbFacade.db.flush()
            dbFacade.db.delete(from_bc)
            
        dbFacade.balances.changeDao.save(to_bc)
        dbFacade.db.commit()
        return { "id" : to_bc.uid }
Esempio n. 24
0
    def list(self, balance_uid):
        dbFacade = self.dbFacade()

        if "all" == balance_uid:
            balance_uids = [userBalance.balance_uid for userBalance in h.authenticated_user().balances]
        else:
            balance = dbFacade.balances.balanceDao.find_by_uid(balance_uid)
            if not balance or not balance.can_see_balance(h.authenticated_user().uid):
                return { "failure": Messages.permissionDenied() }
            balance_uids = [balance.uid]

        sort = {
                "occurred_on": dbFacade.model.BalanceChange.occurred_on,
                "amount": dbFacade.model.BalanceChange.amount,
                "change_category": dbFacade.model.ChangeCategory.name,
                "description": dbFacade.model.BalanceChange.description
            }.get(request.params.get("sort", "occurred_on"), dbFacade.model.BalanceChange.occurred_on)

        conditions = or_(*[dbFacade.model.BalanceChange.balance.has(dbFacade.model.Balance.uid == uid) for uid in balance_uids])

        tags = request.params.getall('tag')
        if tags:
            conditions = and_(conditions, and_(*[dbFacade.model.BalanceChange.tags.any(tag=tag.strip().lower()) for tag in tags if tag is not None and tag.strip() != '']))
 
        changeCategories = request.params.getall('change_category')
        if changeCategories:
            conditions = and_(conditions, and_(*[dbFacade.model.BalanceChange.change_category_uid == value for value in changeCategories if value is not None and value.strip() != '']))
       
        qr = dbFacade.db.query(dbFacade.model.BalanceChange) \
            .options(eagerload('change_category')).join(dbFacade.model.BalanceChange.change_category) \
            .filter(conditions) \
            .order_by([request.params.get("dir", "asc") == "desc" and sort.desc() or sort.asc(), dbFacade.model.BalanceChange.uid.desc()])

        (start_date, end_date) = self._get_dates()

        if start_date:
            qr = qr.filter(dbFacade.model.BalanceChange.occurred_on >= start_date)

        if end_date:
            qr = qr.filter(dbFacade.model.BalanceChange.occurred_on <= end_date)

        balance_changes = qr.all()

        total = len(balance_changes)
        
        subset = Page(balance_changes, item_count=total, current_index=request.environ['pagination.startIndex'], items_per_page=request.environ['pagination.results'])
        return {
            "summary" : {
                "total" : self._total(balance_uids),
                "date_range" : self._ops_for_date_range(balance_uids, start_date, end_date, 
                    tags = request.params.getall('tag'), change_categories = request.params.getall('change_category'))
            },
            "changes": { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid, 
                "change_category_uid" : item.change_category_uid, 
                "change_category" : item.change_category.name, 
                "amount" : Decimal(item.amount), 
                "description" : item.description, 
                "occurred_on": str(item.occurred_on),
                "to_balance_uid": (item.transfer and item.amount < 0) and item.transfer.balance_uid or item.balance_uid,
                "from_balance_uid": item.transfer and (item.amount >=0 and item.transfer.balance_uid or item.balance_uid) or None,
                "tags": [t.tag for t in item.tags]} for item in subset ]
            }
        }
Esempio n. 25
0
    def list(self, balance_uid):
        dbFacade = self.dbFacade()

        balance_uids = dbFacade.balances.balanceDao.get_uids_by_user(h.authenticated_user().uid,
            "all" != balance_uid and [balance_uid] or [])

        if not len(balance_uids):
            return { "failure": Messages.permissionDenied() }

        sort = {
                "transaction_date": dbFacade.model.BalanceChange.transaction_date,
                "amount": dbFacade.model.BalanceChange.amount,
                "category": dbFacade.model.BalanceChange.category,
                "description": dbFacade.model.BalanceChange.description
            }.get(request.params.get("sort", "transaction_date"), dbFacade.model.BalanceChange.transaction_date)

        conditions = or_(*[dbFacade.model.BalanceChange.balance_uid == balance_uid for balance_uid in balance_uids])

        tags = request.params.getall('tag')
        if tags:
            conditions = and_(conditions, and_(*[dbFacade.model.BalanceChange.tags.any(tag=tag.strip().lower()) for tag in tags if tag is not None and tag.strip() != '']))
 
        categories = request.params.getall('category')
        if categories:
            conditions = and_(conditions, and_(*[dbFacade.model.BalanceChange.category == value for value in categories if value is not None and value.strip() != '']))
       
        qr = dbFacade.db.query(dbFacade.model.BalanceChange) \
            .filter(conditions) \
            .order_by(request.params.get("dir", "asc") == "desc" and sort.desc() or sort.asc(), dbFacade.model.BalanceChange.uid.desc())

        (start_date, end_date) = h.get_dates(use_defaults=False)

        if start_date:
            qr = qr.filter(dbFacade.model.BalanceChange.transaction_date >= start_date)

        if end_date:
            qr = qr.filter(dbFacade.model.BalanceChange.transaction_date <= end_date)

        balance_changes = qr.all()

        total = len(balance_changes)
        
        subset = Page(balance_changes, item_count=total, current_index=request.environ['pagination.startIndex'], items_per_page=request.environ['pagination.results'])
        return {
            "summary" : {
                "total" : self._total(balance_uids),
                "date_range" : self._ops_for_date_range(balance_uids, start_date, end_date, 
                    tags = request.params.getall('tag'), categories = request.params.getall('category'))
            },
            "changes": { 
            "totalItems" : total,
            "itemsFound" : len(subset),
            "items" : [{ 
                "uid" : item.uid, 
                "merchant": not len(item.merchant) and _('Unknown') or item.merchant,
                "category" : item.category, 
                "amount" : Decimal(item.amount), 
                "description" : item.description, 
                "transaction_date": str(item.transaction_date),
                "to_balance_uid": (item.transfer and item.amount < 0) and item.transfer.balance_uid or item.balance_uid,
                "from_balance_uid": item.transfer and (item.amount >=0 and item.transfer.balance_uid or item.balance_uid) or None,
                "tags": [t.tag for t in item.tags],
                "bank_description": item.bank_description
                } for item in subset]
            }
        }