def get_category_outcome_per_month(user_id, category_id): ''' :param user_id: :param category_id: :return: dict with outcome per month {month:outcome} ''' outcome_per_month = {key: 0 for key in range(1, 13)} category = Category.get_category(category_id) current_date = datetime.datetime.today() current_year = current_date.year current_month = current_date.month if category.type == 'Current': for i in range(current_month + 1, 13): a = list( Operation.objects.filter(from_category__user_id=user_id, from_category=category.id, date__month=i, date__year=current_year - 1)) outcome_per_month[i] = sum(j.value for j in a) for i in range(1, current_month + 1): a = list( Operation.objects.filter(from_category__user_id=user_id, from_category=category.id, date__month=i, date__year=current_year)) outcome_per_month[i] = sum(j.value for j in a) else: for i in range(current_month + 1, 13): a = list( Operation.objects.filter(to_category__user_id=user_id, to_category=category.id, date__month=i, date__year=current_year - 1)) outcome_per_month[i] = sum(j.value for j in a) for i in range(1, current_month + 1): a = list( Operation.objects.filter(to_category__user_id=user_id, to_category=category.id, date__month=i, date__year=current_year)) outcome_per_month[i] = sum(j.value for j in a) return outcome_per_month
def get_user_operation_by_category(user_id, category_id): ''' :param user_id: :param category_id: :return: All operations with category ''' operation_list = Operation.get_user_operation(user_id) category = Category.get_category(category_id) data = [] for operation in operation_list: if operation.from_category.name == category.name \ or operation.to_category.name == category.name: data.append(operation) return data
def get_user_category_outcome(user_id, category_id): ''' :param user_id: :param category_id: :return: Outcome of the category ''' try: category = Category.get_category(category_id) operation_list = Operation.objects.filter( to_category__user_id=user_id, to_category__name=category.name) outcome = 0 for i in operation_list: outcome += i.value return outcome except ObjectDoesNotExist: return None
def get_user_category_income(user_id, category_id): ''' :param user_id: :param category_id: :return: Total Income of the category ''' try: category = Category.get_category(category_id) operation_list = Operation.objects.filter( from_category__user_id=user_id, from_category__name=category.name) income = 0 for i in operation_list: income += i.value return income except ObjectDoesNotExist: return None
def statistic_category_view(request, category_id): ''' :param request: :param category_id: :return: list of category operations, category total income/outcome and bar plot of income\outcome of the category for the last year ''' category = Category.get_category(category_id) operation_list = Operation.get_user_operation_by_category(request.user, category_id) # category total income category_income = Operation.get_user_category_income(request.user, category_id) # category total outcome category_outcome = Operation.get_user_category_outcome(request.user, category_id) current_month = datetime.datetime.today().month months1 = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'} # make list of months from the past year to current # E.G. if today is February: # months = ['Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', # 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb'] months = [months1[(i % 13)] for i in range(current_month + 1, current_month + 14) if i != 13] # income_per_month is a dict that save income for each month # months are in their number equivalent # months{1:100} means that in Jan user had 100 income income_per_month1 = Operation.get_category_income_per_month(request.user, category_id) # outcome_per_month is a dict that save outcome for each month # months are in their number equivalent # months{1:50} means that in Jan user had 50 outcome outcome_per_month1 = Operation.get_category_outcome_per_month(request.user, category_id) income_per_month = {} outcome_per_month = {} for i in range(current_month + 1, current_month + 14): if i == 13: continue i %= 13 income_per_month[i] = income_per_month1[i] outcome_per_month[i] = outcome_per_month1[i] fig = go.Figure() fig.add_trace(go.Bar( x=months, y=list(income_per_month.values()), name='Income', marker_color='indianred' )) fig.add_trace(go.Bar( x=months, y=list(outcome_per_month.values()), name='Outcome', marker_color='blue' )) fig.update_layout(barmode='group', title={ 'text': f"{category.name} Income\Outcome", 'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top', 'font': {'family': 'Arial', 'size': 20 } }, width=1425, height=600) # html <div> with Bar Chart bar = plot(fig, output_type='div') return render(request, 'statistic_category.html', {'category': category, 'operation_list': operation_list, 'category_income': category_income, 'category_outcome': category_outcome, 'bar': bar})