def expense_edit(request, pk): expense = get_object_or_404(Expense, pk=pk, user=request.user) if expense.is_bill: return HttpResponseRedirect(expense.get_absolute_url()) form = ExpenseForm(instance=expense, user=request.user) if request.method == "POST": form = ExpenseForm(request.POST, instance=expense, user=request.user) if form.is_valid(): expense = form.save(commit=False) expense.user = request.user expense.is_bill = False expense.save() form.save_m2m() return HttpResponseRedirect(expense.get_absolute_url()) return render( request, "expenses/expense_add_edit.html", { "htmltitle": str(expense), "pid": "expense_edit", "expense": expense, "form": form, "mode": "edit", }, )
def post(self, request): form = ExpenseForm(request.POST) jsonstr = request.POST['json_string'] if form.is_valid(): exp_date = form.cleaned_data['date'] comment = form.cleaned_data['comment'] total_cost = form.cleaned_data['total'] else: return HttpResponse('invalid form') expense_dict = json.loads(jsonstr) self.context['expense_form'] = ExpenseForm() try: category = Category.objects.filter(name=expense_dict['category'])[0] itm = None qty= None cst=None for item in expense_dict['items']: itm_name = str(list(item.keys())[0]) itm = Item.objects.all().filter(name=itm_name)[0] qty = float(item[itm_name]['quantity']) cst = int(item[itm_name]['cost']) if qty==0 or cst==0: self.context['message'] = 'Zero value for some items' return render(request, 'expenses/index.html', self.context) expenses = Expense.objects.filter(date=exp_date, category=category) expense=None if len(expenses) == 0: # means no expense yet for the day on the same category expense = Expense(date=exp_date, category=category, comment=comment, cost=total_cost) expense.save() else: # already exists, add total expense = expenses[0] expense.cost+=total_cost expense.comment+='<br>'+comment expense.save() # save the item expense ( as it depends on expense) if len(expense_dict['items']) > 0: itm_exp = ItemExpense(expense=expense, item=itm, quantity=qty, cost=cst) itm_exp.save() self.context['message'] = 'Expense added' return render(request, 'expenses/index.html', self.context) except Exception as e: return HttpResponse(repr(e))
def expense(request, id=0): """ Get or Create/Update an expense """ status = 400 expense = None errors = {} if request.method == 'PUT': data = json.loads(request.body) expense = get_object_or_404(Expense, pk=id, user=request.user) form = ExpenseForm(data, instance=expense) if form.is_valid(): balance = Balance.objects.get(user=request.user) # Reset balance because we're updating an expense. balance.amount -= expense.amount form.save() balance.amount += expense.amount balance.save() status = 200 else: errors = {'errors':form.errors} elif request.method == 'POST': data = json.loads(request.body) form = ExpenseForm(data) if form.is_valid(): form.cleaned_data['user'] = request.user expense = Expense(**form.cleaned_data) expense.save() try: balance = Balance.objects.get(user=request.user) except Balance.DoesNotExist: # This user doesn't have a balance yet, create one. balance = Balance.objects.create(amount=0.0, user=request.user) balance.amount += expense.amount balance.save() status = 201 else: errors = {'errors':form.errors} elif request.method == 'DELETE': expense = get_object_or_404(Expense, pk=id, user=request.user) try: # Make sure to update balance depending on the transaction type. balance = Balance.objects.get(user=request.user) balance.amount -= expense.amount balance.save() expense.delete() except: status = 500 return HttpResponse(status=status) else: try: expense = get_object_or_404(Expense, pk=id) except Expense.DoesNotExist: logging.error('expense does not exist: ' + id) status = 404 response = errors if errors else serialize(expense, ignore=[auth.models.User]) return HttpResponse(content=json.dumps(response), status=status, content_type='application/json')
def create(request): if request.method == 'POST': form = ExpenseForm(request.POST) if form.is_valid(): expense = form.save() expense.payment = constants.CASH expense.save() messages.success(request, 'Expense created') return redirect('expenses:create') else: form = ExpenseForm() context = { 'form': form, } return render( request, 'expenses/create.html', context)
def create(request): """ Create an expense. Update the current Balance. """ status = 201 form = ExpenseForm(request.POST) if form.is_valid(): expense = form.save() try: balance = Balance.objects.get(pk=1) except Balance.DoesNotExist: # We're just now starting the app or something happened to the db, create the expense record. balance = Balance.objects.create(amount=0.0) balance.amount += expense.amount balance.save() else: status = 500 logging.error(form.errors) return HttpResponse(status=status)
def new_expense(request): if request.method == 'POST': form = ExpenseForm(request.POST) if form.is_valid(): form.save() request.user.message_set.create(message="Expense added!") return redirect('expense_new') else: form = ExpenseForm() return render(request, 'expenses/expense.html', {'form': form})
def update(request, id): status = 201 expense = get_object_or_404(Expense, pk=id) old_amount = expense.amount form = ExpenseForm(request.POST, instance=expense) if form.is_valid(): new_expense = form.save() try: balance = Balance.objects.get(pk=1) except Balance.DoesNotExist: logging.error('Missing Balance record. What happened? Panic!') status = 500 else: balance.amount -= old_amount balance.amount += new_expense.amount balance.save() else: logging.error(form.errors) status = 500 return HttpResponse(status=status)
def test_create_form(self): form_data = {} form = ExpenseForm(data=form_data) self.assertFalse(form.is_valid()) form_data = { 'amount': Decimal('10.12'), 'date': datetime.now().strftime('%Y-%m-%d'), 'description': 'Testing expense', 'category': self.category.id, } form = ExpenseForm(data=form_data) self.assertTrue(form.is_valid()) self.assertEqual(Expense.objects.count(), 1) form.save() self.assertEqual(Expense.objects.count(), 2)
def expense_add(request): form = ExpenseForm(user=request.user) if request.method == "POST": form = ExpenseForm(request.POST, user=request.user) if form.is_valid(): inst = form.save(commit=False) inst.user = request.user inst.is_bill = False inst.save() form.save_m2m() return HttpResponseRedirect(reverse("expenses:expense_list")) return render( request, "expenses/expense_add_edit.html", {"htmltitle": _("Add an expense"), "pid": "expense_add", "form": form, "mode": "add",}, )
def create(request): if request.method == "POST": form = ExpenseForm(request.POST) if form.is_valid(): o = form.save() return redirect(reverse("expenses:detail", args=(o.id, ))) else: form = ExpenseForm() return render(request, "expenses/expense_form.html", { 'form': form, })
def update(request, id): o = get_object_or_404(models.Expense, id=id, user=request.user) if request.method == "POST": form = ExpenseForm(request.POST, request.FILES, instance=o) if form.is_valid(): o = form.save() return redirect(reverse("expenses:detail", args=(o.id,))) else: form = ExpenseForm(instance=o) return render(request, "expenses/expense_form.html", { 'form': form, })
def dashboard(request): msg = '' form = ExpenseForm() if request.method == 'POST': form = ExpenseForm(request.POST) if form.is_valid(): expenses = Expenses() expenses.client = request.user expenses.title = form.cleaned_data['title'] expenses.description = form.cleaned_data['description'] expenses.amount = form.cleaned_data['amount'] expenses.currency = form.cleaned_data['currency'] expenses.date = form.cleaned_data['date'] expenses.save() form = ExpenseForm() msg = 'Expense added successfully' return render(request, 'dashboard.html', {'form': form, 'msg': msg})
def create(request): if request.method == "POST": form = ExpenseForm(request.POST) if form.is_valid(): o = form.save() return redirect("expenses:detail", id=o.id) else: # method = GET form = ExpenseForm() d = { 'form': form, } return render(request, "expenses/form.html", d)
def update_expense(request, pk): expense_info = Expense.objects.get(id=pk) expenseform = ExpenseForm(instance=expense_info) if request.user.username: if request.method == "POST": expenseform = ExpenseForm(request.POST, instance=expense_info) if expenseform.is_valid(): expenseform.save() return redirect("/profile/") else: context = { "expenseform": expenseform, "current_date": datetime.now().date(), "expense_info": expense_info, } return render(request, "expenses/update_expense.html", context)
def create(request): if request.method == 'POST': form = ExpenseForm(request.POST) if form.is_valid(): expense = form.save() expense.payment = constants.CASH expense.save() messages.success(request, 'Expense created') return redirect('expenses:create') else: form = ExpenseForm() context = { 'form': form, } return render(request, 'expenses/create.html', context)
def expenses_page(request): if request.user.username: author_id = request.user.id user_expenses = Expense.objects.filter( author=author_id).order_by("-expense_date") user_name = request.user.username # ----------- CHARTS ------------ # Expense pie chart food_amount = Expense.objects.filter(expense_type="food").\ filter(author=author_id).aggregate(Sum("amount")) personal_amount = Expense.objects.filter(expense_type="personal").\ filter(author=author_id).aggregate(Sum("amount")) transportation_amount = Expense.objects.filter(expense_type="transportation").\ filter(author=author_id).aggregate(Sum("amount")) housing_amount = Expense.objects.filter(expense_type="housing").\ filter(author=author_id).aggregate(Sum("amount")) other_amount = Expense.objects.filter(expense_type="other").\ filter(author=author_id).aggregate(Sum("amount")) # Names of the pie chart segments groups = ["Food", "Personal", "Transportation", "Housing", "Other"] # Amounts of the pie chart segments amounts = [ food_amount["amount__sum"], personal_amount["amount__sum"], transportation_amount["amount__sum"], housing_amount["amount__sum"], other_amount["amount__sum"] ] # Segment colors # colors = ["#C0ECCC", "#F6A8A6", "#F9F0C1", "#A5C8E4", "#F4CDA6"] # Pastel colors colors = ["#5cb85c", "#d9534f", "#f5e83b", "#0275d8", "#f0ad4e"] # Bootstrap colors # Custom '$' text = ["$", "$", "$", "$", "$"] # The plot creator pie_plot = Figure( Pie( labels=groups, values=amounts, hoverinfo="text+value", text=text, textinfo="label+percent", textfont=dict(size=15), hole=.3, marker=dict(colors=colors, line=dict(color="#000000", width=3)), )) pie_plot.update_layout( legend=dict(orientation="v", ), title={ 'text': "Overall Expenses per Type (% / $)", 'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top', }, # showlegend=False, ) # This is needed to view the plot in a localized setting (not online) plot_div = plot(pie_plot, output_type="div") # Line Plot # Pandas dataframe of expense model expense_user_data = Expense.objects.filter( author=author_id).all().values() data = pd.DataFrame(expense_user_data) # Converting my dates to accepted Pandas datetime data["expense_date"] = pd.to_datetime(data["expense_date"]) # Indexing via date data.set_index("expense_date", inplace=True) # Sorting by date data = data.sort_values(by=["expense_date"]) # Converting data from daily to weekly and summing the amounts per week scatter_plot_data = data.resample("W-MON").agg({ "amount": "sum", "expense_type": " - ".join }) if Budget.objects.filter(author=author_id).last(): budget_data = Budget.objects.filter(author=author_id).last() budget_line = budget_data.weekly_spending_total else: budget_line = None trace_wk_tot = Scatter(x=scatter_plot_data.index, y=scatter_plot_data.amount, mode="lines+markers", name="lines+markers", line=dict( color="#5cb85c", width=4, ), marker=dict(size=12, )) expense_weekly_data = [ trace_wk_tot ] # This format in case adding additional traces line_plot = Figure(expense_weekly_data) # Line plot instance # Total Budget per week line for comparison if budget_line: line_plot.add_shape( type="line", x0=scatter_plot_data.index.min(), y0=budget_line, x1=scatter_plot_data.index.max(), y1=budget_line, line=dict( color="#d9534f", width=2, dash="dash", ), ) line_plot.update_layout( xaxis_title="Time (Weeks)", yaxis_title="Total Spent ($)", font=dict(size=14, ), yaxis_tickformat="$", title={ 'text': "Total Expenses per Week", 'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top', }, yaxis={"rangemode": "tozero"}, ) plot_div_line = plot(line_plot, output_type="div") # Bar Chart # Gather data: each expense type and associated budget limit via Pandas # expense_type filters food_filter = (data["expense_type"] == "food") personal_filter = (data["expense_type"] == "personal") transportation_filter = (data["expense_type"] == "transportation") housing_filter = (data["expense_type"] == "housing") other_filter = (data["expense_type"] == "other") # expense_date (Current Week) filter previous_monday = date.today() - timedelta(days=date.today().weekday()) next_monday = previous_monday + timedelta(weeks=1) week_filter = ((data.index >= pd.to_datetime(previous_monday)) & (data.index < pd.to_datetime(next_monday))) # Split Current Week data up into expense_type # Pulls the "amount" data based on the above filters and then sums them for the week week_food_amt = data["amount"].loc[week_filter & food_filter].sum() week_personal_amt = data["amount"].loc[week_filter & personal_filter].sum() week_transportation_amt = data["amount"].loc[ week_filter & transportation_filter].sum() week_housing_amt = data["amount"].loc[week_filter & housing_filter].sum() week_other_amt = data["amount"].loc[week_filter & other_filter].sum() spending_array = [ week_food_amt, week_personal_amt, week_transportation_amt, week_housing_amt, week_other_amt ] # Budget Type Limits if Budget.objects.filter(author=author_id).last(): budget_data = Budget.objects.filter(author=author_id).last() budget_food = budget_data.weekly_food budget_personal = budget_data.weekly_personal budget_transportation = budget_data.weekly_transportation budget_housing = budget_data.weekly_housing budget_other = budget_data.weekly_other else: budget_food = None budget_personal = None budget_transportation = None budget_housing = None budget_other = None budget_array = [ budget_food, budget_personal, budget_transportation, budget_housing, budget_other ] # Graph the bar chart types = ["Food", "Personal", "Transport", "Housing", "Other"] bar_trace = [ Bar(name="Expense Totals", x=types, y=spending_array, marker_color=colors, text=spending_array, textposition="auto", showlegend=False), Bar(name="Budget Limits", x=types, y=budget_array, marker_color="#cfb3ff") ] bar_chart = Figure(bar_trace) bar_chart.update_layout( barmode="group", yaxis_title="Total Spent ($)", yaxis_tickformat="$", title={ 'text': "Total Expenses vs Budget Limits per Week", 'y': 0.9, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top', }, legend=dict(orientation="h", ), # showlegend=False, ) # Add the chart to the context and plot in html plot_div_bar = plot(bar_chart, output_type="div") # Budget Form Instance if Budget.objects.last(): budget_info = Budget.objects.last() budgetform = BudgetForm(instance=budget_info) else: budgetform = BudgetForm() # Update Expense Form if Expense.objects.last(): # expense_info = Expense.objects.get(id=pk) # expenseform = ExpenseForm(instance=expense_info) expenseform = ExpenseForm() else: expenseform = ExpenseForm() context = { "user_expenses": user_expenses, "user_name": user_name, "plot_div": plot_div, "plot_div_line": plot_div_line, "plot_div_bar": plot_div_bar, "budgetform": budgetform, "expenseform": expenseform, "current_date": datetime.now().date(), } return render(request, "expenses/expenses.html", context) else: return HttpResponseRedirect("/signup")