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.")
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.')
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'}