예제 #1
0
def _update_transaction(data, *args, **kwargs):

    # use this as data.get(...) would give None
    # wether key is not in JSON or key's value is NULL
    amount_in_json, amount = key_exists(data=data, key='amount')
    processed_at_in_json, processed_at = key_exists(data=data,
                                                    key='processed_at')
    comment_in_json, comment = key_exists(data=data, key='comment')

    if amount_in_json:
        if not amount:
            raise ValidationError('Amount may not be <null>.')
        elif not is_float(amount):
            raise ValidationError('Amount must be a <float> number.')

    if processed_at_in_json:
        if not processed_at:
            raise ValidationError('Process datetime may not be <null>.')
        if not is_timestamp(processed_at):
            raise ValidationError('Process datetime must be UNIX timestamp.')
        elif float(processed_at) > time.time():
            raise ValidationError('Process datetime cannot be in future.')

    if comment_in_json and comment and not (MIN_COMMENT_LEN < len(str(comment))
                                            < MAX_COMMENT_LEN):
        raise ValidationError(
            'Comment must be at least %s max %s characters long.' %
            (MIN_COMMENT_LEN, MAX_COMMENT_LEN))
def _merge_categories(data, current_user):
    subject_in_json, subject_id = key_exists(data=data, key='subject_id')
    target_in_json, target_id = key_exists(data=data, key='target_id')

    for key, name in ((subject_in_json, "'subject_id'"), (target_in_json,
                                                          "'target_id'")):
        if not key:
            raise ValidationError(f"{name} missing.")

    subject_id = validate_natural_number(subject_id, name="'subject_id")
    target_id = validate_natural_number(target_id, name="'target_id")

    subject = Category.query.filter_by(user_id=current_user.id,
                                       id=subject_id).first()
    target = Category.query.filter_by(user_id=current_user.id,
                                      id=target_id).first()

    if not subject:
        raise ValidationError("Subject category not found.", 404)
    if not target:
        raise ValidationError("Target category not found.", 404)
    if subject_id == target_id:
        raise ValidationError("Category cannot be merged into itself.")

    for ascendent in target.get_ascendants():
        if ascendent.id == subject.id:
            raise ValidationError(
                "Category cannot be merged into any of its subcategories.")
예제 #3
0
def update_transaction(data, current_user, cat, trans):
    amount_in_json, amount = key_exists(data=data, key='amount')
    processed_at_in_json, processed_at = key_exists(
        data=data, key='processed_at')
    comment_in_json, comment = key_exists(data=data, key='comment')

    # if any of them changed
    if amount_in_json and float(trans.amount) != float(amount) or \
       comment_in_json and trans.comment != comment or \
       processed_at_in_json and \
       (processed_at != datetime2timestamp(trans.processed_at)):
        trans.updated_at = datetime.utcnow()

    if amount_in_json:
        trans.amount = amount
    if processed_at_in_json:
        trans.processed_at = timestamp2datetime(processed_at)
    if comment_in_json:
        trans.comment = comment

    try:
        db.session.commit()
    except SQLAlchemyError:
        db.session.rollback()
        return 'Internal Server Error.', 500

    return trans.as_dict(), 200, {'key': 'transaction'}
def _update_category(data, user, cat):
    cat_to_change = cat

    # use this as data.get(...) would give None
    # whether key is not in JSON or key's value is null
    title_in_json, title = key_exists(data=data, key='title')
    description_in_json, description = key_exists(data=data, key='description')
    parent_id_in_json, parent_id = key_exists(data=data, key='parent_id')

    if title_in_json:
        if not title:
            raise ValidationError('Title may not be <null>.')
        elif not MIN_TITLE_LEN <= len(title) <= MAX_TITLE_LEN:
            raise ValidationError(
                'Title must be at least %s max %s characters long.' %
                (MIN_TITLE_LEN, MAX_TITLE_LEN))

    if description_in_json:
        if description is None:
            raise ValidationError('Description may not be <null>.')
        elif not (MIN_DESCRIPTION_LEN <= len(description) <=
                  MAX_DESCRIPTION_LEN):
            raise ValidationError(
                'Description must be at least %s max %s characters long.' %
                (MIN_DESCRIPTION_LEN, MAX_DESCRIPTION_LEN))

    if parent_id_in_json and parent_id is not None:
        if not Category.query.filter_by(id=parent_id, user_id=user.id).first():
            raise ValidationError("Parent doesn't exist.")
        elif int(parent_id) == cat_to_change.id:
            raise ValidationError("Parent may not be itself.")
        elif int(parent_id) in map(lambda child: child.id,
                                   cat_to_change.get_descendents()):
            raise ValidationError(
                "Parent may not be descendent of the category being updated.")

    ti = title if title_in_json and title else cat_to_change.title
    pi = parent_id if parent_id_in_json and parent_id else\
        cat_to_change.parent_id

    cats = Category.query.filter_by(user_id=user.id, title=ti,
                                    parent_id=pi).all()

    for cat in cats:
        # if not the category to change itself
        # then it breaks the unique together constraint
        if cat is not cat_to_change:
            raise ValidationError(
                'Title and parent_id must be unique together.')
def _create_category(data, current_user):

    # use this as data.get(...) would give None
    # whether key is not in JSON or key's value is null
    title_in_json, title = key_exists(data=data, key='title')
    description_in_json, description = key_exists(data=data, key='description')
    parent_id_in_json, parent_id = key_exists(data=data, key='parent_id')

    if title_in_json:
        if not title:
            raise ValidationError('Title may not be <null>.')
        elif not MIN_TITLE_LEN <= len(title) <= MAX_TITLE_LEN:
            raise ValidationError(
                'Title must be at least %s max %s characters long.' %
                (MIN_TITLE_LEN, MAX_TITLE_LEN))
    else:
        raise ValidationError('Title required.')

    if description_in_json:
        if description is None:
            raise ValidationError('Description may not be <null>.')
        elif not (MIN_DESCRIPTION_LEN <= len(description) <=
                  MAX_DESCRIPTION_LEN):
            raise ValidationError(
                ('Description must be at least %s max %s characters long.' %
                 (MIN_DESCRIPTION_LEN, MAX_DESCRIPTION_LEN)))

    # Not necessary to check if <parent_id> is int (or can be converted to int)
    # because <filter_by> also finds integer ids as strings.
    if parent_id_in_json and parent_id and not Category.query.filter_by(
            id=parent_id, user_id=current_user.id).first():
        raise ValidationError("Parent doesn't exist.")

    unique_together = not Category.query.filter_by(
        user_id=current_user.id, parent_id=parent_id, title=title).first()
    if not unique_together:
        raise ValidationError('Title and parent_id must be unique together.')
예제 #6
0
def update_category(data, current_user, cat):
    title = data.get('title')
    description_in_json, description = key_exists(data=data, key='description')
    parent_id_in_json, parent_id = key_exists(data=data, key='parent_id')

    # if any of them changed
    if cat.title != title or \
       description_in_json and cat.description != description or \
       parent_id_in_json and cat.parent_id != parent_id:
        cat.updated_at = datetime.utcnow()

    cat.title = title if title else cat.title
    if description_in_json:
        cat.description = description
    if parent_id_in_json:
        cat.parent_id = parent_id

    try:
        db.session.commit()
    except SQLAlchemyError:
        db.session.rollback()
        return 'Internal Server Error', 500

    return cat.as_dict(), 200, {'key': 'category'}