Exemple #1
0
def new_budget_view(request):
	if request.method == 'POST':
		form = BudgetForm(request.POST)
		if form.is_valid():
			amount = form.cleaned_data['budget_amount']
			weekly = form.cleaned_data['is_weekly']
			month = datetime.today().month
			year = datetime.today().year
			end_date = datetime.today()
			if weekly:
				today = datetime.today().weekday()
				difference = 6-today
				delta = timedelta(days=difference)
				end_date = end_date+delta
			else:
				end_day = calendar.monthrange(year, month)[1]
				end_date = date(year, month, end_day)

			model = BudgetModel(user_account=request.user,
				budget_amount=amount, is_weekly=weekly,
				budget_month=month, budget_year=year,
				end_date=end_date)
			model.save()
			return HttpResponseRedirect('/accounts/profile')

	context = RequestContext(request)
	context['form'] = BudgetForm()
	context.update(csrf(request))
	return render(request, 'budget/newbudget.html', context)
Exemple #2
0
def new_budget_view(request):
    if request.method == 'POST':
        form = BudgetForm(request.POST)
        if form.is_valid():
            amount = form.cleaned_data['budget_amount']
            weekly = form.cleaned_data['is_weekly']
            month = datetime.today().month
            year = datetime.today().year
            end_date = datetime.today()
            if weekly:
                today = datetime.today().weekday()
                difference = 6 - today
                delta = timedelta(days=difference)
                end_date = end_date + delta
            else:
                end_day = calendar.monthrange(year, month)[1]
                end_date = date(year, month, end_day)

            model = BudgetModel(user_account=request.user,
                                budget_amount=amount,
                                is_weekly=weekly,
                                budget_month=month,
                                budget_year=year,
                                end_date=end_date)
            model.save()
            return HttpResponseRedirect('/accounts/profile')

    context = RequestContext(request)
    context['form'] = BudgetForm()
    context.update(csrf(request))
    return render(request, 'budget/newbudget.html', context)
    def test_form_save(self):
        from budget.forms import BudgetForm

        form_data = {'name': 'foo',
                     'start_date': date.today()}
        form = BudgetForm(data=form_data)

        self.assertTrue(form.is_valid())
Exemple #4
0
def item(request, budget_id):
    budget = get_object_or_404( Budget, id = budget_id )
    
    if request.method == 'GET':
        form = BudgetForm( instance = budget )
    elif request.method == 'POST':
        form = BudgetForm(data = request.POST, instance = budget)
        if form.is_valid():
            data = form.cleaned_data
            form.save()
            budget.update_budgetlines()
            
            sum_natures = 0
            for n in ['fo','mi','sa','eq']:
                if n in data and data[n]:
                    sum_natures += data[n]
            
            if sum_natures > budget.get_amount_left():
                error_msg( request, u"Montant disponible insuffisant pour cette répartition." )
            else:
                for nature in ['fo','mi','sa','eq']:
                    if data[nature] or data[nature] == 0:
                        sub_budget, created = Budget.objects.get_or_create(
                            team = budget.team,
                            name = "%s - %s" % (budget.name, nature.upper()),
                            default_origin = budget.default_origin,
                            budget_type = budget.budget_type,
                            tva_code = budget.tva_code,
                            domain = budget.domain,
                            default_nature = nature.upper()
                        )
                        if data[nature] > 0:
                            bl = sub_budget.credit( data[nature] )
                            bl.product = u"Répartition"
                            bl.save()
                        
                            bl = budget.debit( data[nature] )
                            bl.product = u"Répartition vers %s" % nature.upper()
                            bl.save()
                
                # if budget.get_amount_left() == 0:
                #   budget.is_active = False
                #   budget.save()
                #   for bl in BudgetLine.objects.filter( budget_id = budget.id ):
                #       bl.is_active = False
                #       bl.save()
                #   info_msg( request, "Budget modifié avec succès. Il a été automatiquement archivé car son montant dispo est égal à 0.")
                # else:
                info_msg(request, "Budget modifié avec succès.")
                return redirect('budgets')
    else:
        return redirect('error')
    
    return render(request, 'budget/item.html', {
        'budget': budget,
        'form': form
    })
    def test_form_save_should_populate_slug_field(self):
        from budget.forms import BudgetForm

        form_data = {'name': 'Foo Bar',
                     'start_date': date.today()}
        form = BudgetForm(data=form_data)

        self.assertTrue(form.is_valid())

        form.save()
        self.assertEqual('foo-bar', form.instance.slug)
Exemple #6
0
def new(request):
    if request.method == 'GET':
        form = BudgetForm()
    elif request.method == 'POST':
        form = BudgetForm(data = request.POST)
        if form.is_valid():
            data = form.cleaned_data

            if data.get('all_natures', None) and data['all_natures'] >= 0:
                budget = form.save(commit = False)
                budget.name = "[%s] %s [%s]" % (
                    data['team'].shortname,
                    data['name'],
                    data['default_origin']
                )
                budget.save()
                if data['all_natures'] > 0:
                    bl = budget.credit(data["all_natures"])
                    bl.product = u"Initial"
                    bl.save()
                info_msg(request, "Budget '%s' ajouté avec succès." % budget.name)
            else:
                for nature in ['fo','mi','sa','eq']:
                    if data.get(nature, None) and data[nature] >= 0:
                        budget = Budget.objects.create(
                            team = data['team'],
                            name = "[%s] %s - %s [%s]" % (
                                data['team'].shortname,
                                data['name'],
                                nature.upper(),
                                data['default_origin']
                            ),
                            default_origin = data['default_origin'],
                            budget_type = data['budget_type'],
                            tva_code = data['tva_code'],
                            domain = data['domain'],
                            default_nature = nature.upper()
                        )
                        info_msg(request, "Budget '%s' ajouté avec succès." % budget.name)
                        if data[nature] > 0:
                            bl = budget.credit(data[nature])
                            bl.product = u"Initial"
                            bl.save()

            return redirect('budget:list')
    else:
        return redirect('error')
        
    return render(request, 'budget/form.html',{
        'form': form
    })
Exemple #7
0
def save_budget(request):
    if request.method == 'POST':
        budget = Budget()
        form = BudgetForm(request.POST, instance=budget)
        if form.is_valid():
            try:
                form.save()
            except Exception:
                return mail_response('false')
            sendmail(form)
            return mail_response('true')
        else:
            return mail_response('false')
    else:
        raise Http404
Exemple #8
0
def item(request, budget_id):
    budget = get_object_or_404(Budget, id=budget_id)

    if request.method == 'GET':
        form = BudgetForm(instance=budget)
    elif request.method == 'POST':
        form = BudgetForm(data=request.POST, instance=budget)
        if form.is_valid():
            data = form.cleaned_data
            form.save()
            budget.update_budgetlines()

            sum_natures = 0
            for n in ['fo', 'mi', 'sa', 'eq']:
                if n in data and data[n]:
                    sum_natures += data[n]

            if sum_natures > budget.get_amount_left():
                error_msg(
                    request,
                    u"Montant disponible insuffisant pour cette répartition.")
            else:
                for nature in ['fo', 'mi', 'sa', 'eq']:
                    if data[nature] or data[nature] == 0:
                        sub_budget, created = Budget.objects.get_or_create(
                            team=budget.team,
                            name="%s - %s" % (budget.name, nature.upper()),
                            default_origin=budget.default_origin,
                            budget_type=budget.budget_type,
                            tva_code=budget.tva_code,
                            domain=budget.domain,
                            default_nature=nature.upper())
                        if data[nature] > 0:
                            bl = sub_budget.credit(data[nature])
                            bl.product = u"Répartition"
                            bl.save()

                            bl = budget.debit(data[nature])
                            bl.product = u"Répartition vers %s" % nature.upper(
                            )
                            bl.save()

                # if budget.get_amount_left() == 0:
                #   budget.is_active = False
                #   budget.save()
                #   for bl in BudgetLine.objects.filter( budget_id = budget.id ):
                #       bl.is_active = False
                #       bl.save()
                #   info_msg( request, "Budget modifié avec succès. Il a été automatiquement archivé car son montant dispo est égal à 0.")
                # else:
                info_msg(request, "Budget modifié avec succès.")
                return redirect('budgets')
    else:
        return redirect('error')

    return render(request, 'budget/item.html', {
        'budget': budget,
        'form': form
    })
Exemple #9
0
def post_budget(request):
    if Budget.objects.last():
        budget_info = Budget.objects.last()
    else:
        budgetform = BudgetForm()

    if request.user.username:
        if request.method == "POST":
            author = Budget(author=request.user)
            budgetform = BudgetForm(request.POST, instance=author)
            if budgetform.is_valid():
                author.save()
                return redirect("/profile/")

            else:
                budgetform = BudgetForm(instance=budget_info)

            return render(request, 'expenses.html', {'budgetform': budgetform})
Exemple #10
0
def new(request):
    if request.method == 'GET':
        form = BudgetForm()
    elif request.method == 'POST':
        form = BudgetForm(data=request.POST)
        if form.is_valid():
            data = form.cleaned_data
            if data['all_natures'] or data["all_natures"] == 0:
                budget = form.save()
                if data['all_natures'] > 0:
                    bl = budget.credit(data["all_natures"])
                    bl.product = u"Initial"
                    bl.save()
            else:
                for nature in ['fo', 'mi', 'sa', 'eq']:
                    if data[nature] or data[nature] == 0:
                        budget = Budget.objects.create(
                            team=data['team'],
                            name="[%s] %s [%s] - %s" %
                            (data['team'].shortname, data['name'],
                             data['default_origin'], nature.upper()),
                            default_origin=data['default_origin'],
                            budget_type=data['budget_type'],
                            tva_code=data['tva_code'],
                            domain=data['domain'],
                            default_nature=nature.upper())
                        if data[nature] > 0:
                            bl = budget.credit(data[nature])
                            bl.product = u"Initial"
                            bl.save()

            info_msg(request, "Budget ajouté avec succès.")
            return redirect('budgets')
    else:
        return redirect('error')

    return render(request, 'budget/form.html', {'form': form})
Exemple #11
0
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")