You are on page 1of 52

GURU GOBIND SINGH

INDRAPRASTHA
UNIVERSITY

A Project Report
on

Home Budget System

Submitted by: Rony Roy, Roshni Bisht, Sonali Mehla, Yash Goyal
Course: BCA 3rd Semester
Batch: 2015-18

ACKNOWLEDGEMENT
If words are considered as a symbol of approval and token of
appreciation, then let the words play the heralding role expressing
my gratitude.
The satisfaction that accompanies that the successful completion of
any task would be incomplete without the mention of people whose
ceaseless cooperation made it possible, whose constant guidance
and encouragement crown all efforts with success. We are grateful
to our project supervisor Dr. Latika Kharb for the guidance,
inspiration and constructive suggestions that helped us in the
preparation of this project. We also thank our fellow classmates who
have helped in successful completion of the project.

CERTIFICATE
This is to certify that the project work under titled as

Home Budget
Is the bona fide work of
Rony Roy, Roshni Bisht, Sonali Mehla, Yash Goyal
during this project submission as a partial fulfillment of the
requirement for the Bachelor of Computer Application, of the
GGSIPU University, New Delhi.

__________________

Project Supervisor

Table of contents
Sr. No Topic
No
1
2
3
4
5
6
7
8
9

Page
Introduction
Proposed System
System Requirements
Data Flow Diagram
Tables Used
Screenshots
Coding
Conclusion
Bibliography

1
2
3
4
5
7
11
47
48

INTRODUCTION
The project titled Home Budget is home budgeting
software that helps you keep track of your income and dayto-day expenses and set realistic budget goals. At a glance,
you can see exactly what comes in and goes out, so you can
better manage your money. Our budget planner will show
you where your money is going and how to save more. The
project Home Budget is developed in C++, which mainly
focuses on basic operations like adding your income
sources, subtracting your monthly expenses, carrying your
savings of the month to the next month. You can even
make a category list of your monthly income sources and
expenses for your better convenience.

Home Budget is a windows application written for


Windows operating systems, using powerful IDE
Ultimate++, designed to help drawing up a budget to
control your household costs and makes it easier to
understand how close your outgo is to your income. Our
software is easy to use it features a familiar and well
thought-out, an attractive user interface. You can easily
look back data of previous month to compare with present.
You can also see where you are spending the most.

1|Page

PROPOSED SYSTEM
Proposed system is an automated Home Budgeting
software. Through our software user can manage his
monthly budget in quick time and figure out his total takehome monthly income and compare it to his expenses Our
proposed system has the following advantages.

User friendly interface

Fast access to database

Less error

More Storage Capacity

Look and Feel Environment

Quick transaction

All the manual difficulties in managing the Budget have


been rectified by implementing computerization.

2|Page

SYSTEM REQUIREMENTS
This Home Budget software can be used in windows
10/8/7, Windows XP and Windows NT, not supported for
any other platform such as Solaris, Macintosh and UNIX.
The system must
requirements.

meet

the

3|Page

following

hardware

1Ghz Processor
512 MB of RAM
50 MB of Hard Disk

Data Flow Diagram


LEVEL 1
New
Category
Edit
Category

Groups

Delete
Category

LEVEL 1
New
Product

Edit
Product

Delete
Product

4|Page

Categories

TABLES USED
Table Name: Dates
Field Name

Data Type

Description

ID

Integer

PRIMARY_KEY

DT

Date

AUTO_INCREMENT

Table Name: Groups


Field Name

Data Type

Description

ID

Integer

PRIMARY_KEY

NAME

String (500)

Field Name

Data Type

Description

ID

Integer

PRIMARY_KEY

GR_ID

Integer

Index

NAME

String (500)

DEFVALUE

Double

PM

Integer

INNEWMONTH

Integer

AUTO_INCREMENT

Table Name: Categories

5|Page

AUTO_INCREMENT

Table Name: Money


Field Name

Data Type

Description

ID

Integer

PRIMARY_KEY

DT_ID

Integer

Index

CAT_ID

Integer

Index

VALUE

Double

PM

Integer

DT

Date

DESC

String (1024)

6|Page

AUTO_INCREMENT

Screenshots
Login Screen

Splash Screen

7|Page

Main Window

Add New Month

Add New Month

8|Page

Add New Category

Add New Category

Add New Product

Add New Product

9|Page

Help Window

About Window

10 | P a g e

Coding
HomeBudget.h
#ifndef _HomeBudget_HomeBudget_h
#define _HomeBudget_HomeBudget_h

class HomeBudgetHelp : public HelpWindow


{
public:
HomeBudgetHelp();
virtual Topic AcquireTopic(const String& topic);
};

class HomeBudget : public WithHomeBudgetLayout<TopWindow>


{
public:
typedef HomeBudget CLASSNAME;

GridCtrl groups;
GridCtrl categories;
GridCtrl money;
GridCtrl mostpr;
GridCtrl mostcat;
Splitter spl;
DropDate dt;
DropGrid dlpm, category, months, yesno, plusminus;
EditDouble defval, val;
EditStringNotNull eg, ec;

11 | P a g e

EditString es;

int dtid;
int lang;

HomeBudget();

void NewGroup();
void NewCategory();

void InsertGroup();
void UpdateGroup();
void RemoveGroup();
void ChangeGroup();

void InsertCategory();
void UpdateCategory();
void RemoveCategory();
void LoadCategories(int group_id);
void UpdateCategories();

void InsertMoney();
void UpdateMoney();
void RemoveMoney();

void InsertDate();
void UpdateDate();
void RemoveDate();
void ChangeDate();
void NewDate();
void AcceptedDate();

12 | P a g e

void LoadDates();
void LoadGroups();

void UpdateSummary();
void ClearSummary();
void UpdateValue();
void GenMonthList(int year);
void Serialize(Stream &s);
void Options();
void About();
void Setup();

void Help();

void SetRest(StaticText &rest, float r);


int GetCategorySign();

void ClearAll();

void LoadMoney(int did);


void EnableMoney(int cnt = -1);

};

#endif

13 | P a g e

HomeBudget.cpp
#include <CtrlLib/CtrlLib.h>
#include <DropGrid/DropGrid.h>
#include <GridCtrl/GridCtrl.h>
#include <plugin/sqlite3/lib/sqlite3.h>
#include <plugin/sqlite3/Sqlite3.h>

using namespace Upp;

#define IMAGEFILE <HomeBudget/HomeBudget.iml>


#define IMAGECLASS Images
#include <Draw/iml.h>

#define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>


#define MODEL <HomeBudget/HomeBudget.sch>

#include <Sql/sch_schema.h>
#include <Sql/sch_header.h>
#include <Sql/sch_source.h>

#define LAYOUTFILE <HomeBudget/HomeBudget.lay>


#include <CtrlCore/lay.h>

#define TOPICFILE <HomeBudget/src.tpp/all.i>


#include <Core/topic_group.h>
#define TOPICFILE <HomeBudget/help.tpp/all.i>
#include <Core/topic_group.h>

#define TFILE <HomeBudget/HomeBudget.t>


#include <Core/t.h>

14 | P a g e

#include "HomeBudget.h"

struct ConvMonth : Convert


{
Value Format(const Value &q) const
{
Date dt = (Date) q;
return q.IsNull() ? "" : UPP::Format("%Month %.4d", dt.month, dt.year);
}
};

struct ConvDouble : Convert


{
Value Format(const Value &q) const
{
return q.IsNull() ? Null : UPP::Format("%.2f", q);
}
};

struct DispPM : GridDisplay


{
virtual void Paint(Draw &w, int x, int y, int cx, int cy, const Value &val,
dword style,
Color &fg, Color &bg, Font &fnt, bool found, int fs, int fe)
{
if(!val.IsNull())
{
int t = int(val) < 0 ? 0 : 1;
SetCenterImage(t ? Images::Plus : Images::Minus);
}
else

15 | P a g e

SetCenterImage(Null);
GridDisplay::Paint(w, x, y, cx, cy, Value(""), style, fg, bg, fnt, found, fs,
fe);
}
};

HomeBudget::HomeBudget()
{
lang = 0;
}

void HomeBudget::Setup()
{
CtrlLayout(*this, String(t_("Home Budget")));

Icon(Images::SmallIcon());
LargeIcon(Images::LargeIcon());

tab.Add(money.SizePos(), t_("Expenses"));
tab.Add(spl.Horz(groups, categories), t_("Categories"));
spl.SetPos(2000);

money.AddIndex(ID);
money.AddColumn(CAT_ID, t_("Category")).Edit(category).SetConvert(category);
money.AddColumn(PM, t_("Plus /
Minus")).SetDisplay(Single<DispPM>()).Edit(plusminus);
money.AddColumn(VALUE,
t_("Value")).Edit(val).Default(0).SetConvert(Single<ConvDouble>());
money.AddColumn(DT, t_("When")).Edit(dt).Default(GetSysDate());
money.AddColumn(DESC, t_("Describe")).Edit(es);
money.Appending().Removing().Editing().Accepting().Canceling();
money.RejectNullRow();
money.WhenInsertRow = THISBACK(InsertMoney);

16 | P a g e

money.WhenUpdateRow = THISBACK(UpdateMoney);
money.WhenRemoveRow = THISBACK(RemoveMoney);
money.SetToolBar();

Date dt = GetSysDate();
dt.day = 1;

month.AddIndex(ID);
month.AddColumn(DT,
t_("Month")).Edit(months).SetConvert(Single<ConvMonth>()).Default(dt);
month.Appending().Removing().Editing().Accepting().Canceling();
month.WhenInsertRow = THISBACK(InsertDate);
month.WhenUpdateRow = THISBACK(UpdateDate);
month.WhenRemoveRow = THISBACK(RemoveDate);
month.WhenChangeRow = THISBACK(ChangeDate);
month.WhenAcceptedRow = THISBACK(AcceptedDate);
month.WhenNewRow

= THISBACK(NewDate);

month.SetToolBar();

groups.AddIndex(ID);
groups.AddColumn(NAME, t_("Name")).Edit(eg);
groups.Appending().Removing().Editing().Accepting().Canceling();
groups.RejectNullRow();
groups.SetToolBar();
groups.WhenInsertRow = THISBACK(InsertGroup);
groups.WhenUpdateRow = THISBACK(UpdateGroup);
groups.WhenRemoveRow = THISBACK(RemoveGroup);
groups.WhenChangeRow = THISBACK(ChangeGroup);

categories.AddIndex(ID);
categories.AddColumn(NAME, t_("Name")).Edit(ec);
categories.AddColumn(DEFVALUE, t_("Default
Value")).Edit(defval).SetConvert(Single<ConvDouble>());

17 | P a g e

categories.AddColumn(PM, t_("Plus /
Minus")).Edit(dlpm).SetConvert(dlpm).Default(-1);
categories.AddColumn(INNEWMONTH, t_("Default For New
Month")).Edit(yesno).SetConvert(yesno).Default(0);
categories.WhenInsertRow = THISBACK(InsertCategory);
categories.WhenUpdateRow = THISBACK(UpdateCategory);
categories.WhenRemoveRow = THISBACK(RemoveCategory);
categories.WhenAcceptedRow = THISBACK(UpdateCategories);
categories.Appending().Removing().Editing();
categories.RejectNullRow();
categories.SetToolBar();

mostpr.AddColumn(t_("Name"));
mostpr.AddColumn(t_("Amount")).SetConvert(Single<ConvDouble>()).AlignCenter()
;
mostcat.AddColumn(t_("Name"));
mostcat.AddColumn(t_("Amount")).SetConvert(Single<ConvDouble>()).AlignCenter(
);

tabmost.Add(mostpr.SizePos(), t_("Product"));
tabmost.Add(mostcat.SizePos(), t_("Category"));

dlpm.Add(-1, t_("Minus")).Add(1, t_("Plus"));


plusminus.Add(-1, t_("Minus")).Add(1, t_("Plus"));
yesno.Add(0, t_("No")).Add(1, t_("Yes"));

GenMonthList(dt.year);

SQL * Delete(MONEY).Where(IsNull(CAT_ID));

LoadDates();
LoadGroups();

UpdateCategories();

18 | P a g e

if(month.GetCount() > 0)
{
month.GoEnd();
UpdateSummary();
}

EnableMoney();
Sizeable().Zoomable();

category <<= THISBACK(UpdateValue);


exit <<= THISBACK(Close);
options <<= THISBACK(Options);
about <<= THISBACK(About);
help <<= THISBACK(Help);

category.Resizeable(false).Header(false);
category.AddPlus(THISBACK(NewCategory));
}

void HomeBudget::Serialize(Stream &s)


{
int version = 1;
s / version;
SerializePlacement(s);
s % spl;
s % lang;
//s % categories;
//s % money;
}

void HomeBudget::GenMonthList(int year)

19 | P a g e

{
months.Clear();

int curr_year = GetSysDate().year;


int max_year = max(year,curr_year);

for(int scan_year = min(year, curr_year) - 1; scan_year <= max_year;


scan_year++)
for(int i = 0; i < 12; i++)
months.Add(Date(scan_year, i + 1, 1), Format("%Month %.4d", i + 1,
scan_year));
}

void HomeBudget::LoadMoney(int dtid)


{
money.Clear();
SQL * Select(ID, CAT_ID, PM, VALUE, DT, DESC).From(MONEY).Where(DT_ID ==
dtid);
while(SQL.Fetch())
{
money.Add();
money(ID) = SQL[ID];
money(CAT_ID) = SQL[CAT_ID];
money(PM) = SQL[PM];
money(VALUE) = SQL[VALUE];
money(DT) = SQL[DT];
money(DESC) = SQL[DESC];
}
}

void HomeBudget::LoadDates()
{
month.Clear();

20 | P a g e

SQL * Select(ID, DT).From(DATES);


while(SQL.Fetch())
month.Add(SQL);
}

void HomeBudget::LoadGroups()
{
groups.Clear();
SQL * Select(ID, NAME).From(GROUPS);
while(SQL.Fetch())
groups.Add(SQL);

if(!groups.IsEmpty())
groups.SetCursor(0);
else
categories.Disable();
}

void HomeBudget::LoadCategories(int group_id)


{
categories.Clear();
SQL * Select(ID, NAME, DEFVALUE, PM, INNEWMONTH).From(CATEGORIES).Where(GR_ID
== group_id);
while(SQL.Fetch())
categories.Add(SQL);
}

int HomeBudget::GetCategorySign()
{
SQL * Select(PM).From(CATEGORIES).Where(ID == money.Get(CAT_ID));
Value v = SQL.Fetch() ? SQL[0] : Value(0);
return v;

21 | P a g e

void HomeBudget::UpdateCategories()
{
category.Clear();
SQL & Select(ID.Of(CATEGORIES), NAME.Of(CATEGORIES), NAME.Of(GROUPS))
.From(CATEGORIES, GROUPS)
.Where(GR_ID == ID.Of(GROUPS))
.OrderBy(NAME.Of(GROUPS), NAME.Of(CATEGORIES));

while(SQL.Fetch())
category.Add(SQL[0], Format("%s - %s", SQL[2], SQL[1]));
}

void HomeBudget::InsertGroup()
{
try
{
SQL & Insert(GROUPS)
(NAME, groups(1));
groups(0) = SQL.GetInsertedId();

categories.Clear();
categories.Enable();
}
catch(SqlExc &e)
{
groups.CancelInsert();
Exclamation("[* " + DeQtfLf(e) + "]");
}

22 | P a g e

void HomeBudget::UpdateGroup()
{
try
{
SQL & ::Update(GROUPS)
(NAME, groups(1))
.Where(ID == groups(0));
}
catch(SqlExc &e)
{
groups.CancelUpdate();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::RemoveGroup()
{
if(categories.IsEmpty())
{
SQL & Delete(GROUPS).Where(ID == groups(ID));

if(groups.GetCount() == 1)
categories.Disable();
}
else
{
PromptOK(t_("You can't remove this group. It is not empty."));
groups.CancelRemove();
}
}

23 | P a g e

struct AddNewCat : WithNewCategoryLayout<TopWindow>


{
typedef AddNewCat CLASSNAME;
bool newgroup;

AddNewCat()
{
newgroup = false;
CtrlLayoutOKCancel(*this, t_("New Item"));
addgroup.SetImage(Images::SmallPlus());
addgroup <<= THISBACK(NewGroup);
groups <<= THISBACK(SelGroup);
addgroup.NoWantFocus();

int cnt = 0;
SQL * Select(ID, NAME).From(GROUPS);
while(SQL.Fetch())
{
groups.Add(SQL[ID], SQL[NAME]);
cnt++;
}

bool isgroup = cnt > 0;


if(isgroup)
groups.SetIndex(0);
else
ok.Disable();

pm = 1;
}

void SelGroup()

24 | P a g e

{
ok.Enable();
}

void NewGroup()
{
WithNewGroupLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, t_("New Category"));
if(dlg.Execute() == IDOK)
{
try
{
SQL & Insert(GROUPS)(NAME, ~dlg.name);
int64 id = SQL.GetInsertedId();
groups.Add(id, ~dlg.name);
groups <<= id;
ok.Enable();
newgroup = true;
}
catch(SqlExc &e)
{
Exclamation("[* " + DeQtfLf(e) + "]");
}
}
}
bool IsNewGroup() { return newgroup; }
};

void HomeBudget::NewCategory()
{
AddNewCat dlg;

25 | P a g e

if(dlg.Execute() == IDOK)
{
try
{
SQL & Insert(CATEGORIES)
(GR_ID, ~dlg.groups)
(NAME, ~dlg.name)
(DEFVALUE, 0)
(PM, dlg.pm == 0 ? 1 : -1)
(INNEWMONTH, 0);

int64 id = SQL.GetInsertedId();
UpdateCategories();
money.Set(CAT_ID, id);
UpdateValue();

int gid = ~dlg.groups;

if(dlg.IsNewGroup())
{
groups.Add(Value(gid), dlg.groups.GetValue());
groups.GoEnd();
categories.Enable();
}
int c = groups.GetCursor();
if(c >= 0 && gid == groups(c, 0))
LoadCategories(gid);
}
catch(SqlExc &e)
{
Exclamation("[* " + DeQtfLf(e) + "]");
}

26 | P a g e

}
}

void HomeBudget::InsertCategory()
{
try
{
SQL & Insert(CATEGORIES)
(GR_ID, groups(ID))
(NAME, categories(NAME))
(DEFVALUE, categories(DEFVALUE))
(PM, categories(PM))
(INNEWMONTH, categories(INNEWMONTH));

categories(0) = SQL.GetInsertedId();
}
catch(SqlExc &e)
{
categories.CancelInsert();
Exclamation("[* " + DeQtfLf(e) + "]");
}

void HomeBudget::UpdateCategory()
{
try
{
SQL & ::Update(CATEGORIES)
(NAME, categories(NAME))
(DEFVALUE, categories(DEFVALUE))
(PM, categories(PM))

27 | P a g e

(INNEWMONTH, categories(INNEWMONTH))
.Where(ID == categories(ID));

UpdateSummary();
}
catch(SqlExc &e)
{
categories.CancelUpdate();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::ChangeGroup()
{
LoadCategories(groups(ID));
}

void HomeBudget::RemoveCategory()
{
try
{
SQL * Select(CAT_ID, NAME)
.From(MONEY, CATEGORIES)
.Where(CAT_ID == categories(ID) && ID.Of(CATEGORIES) == categories(ID))
.Limit(1);

if(SQL.Fetch())
{
PromptOK(Format(t_("Item '%s' can't be removed. It is used in
calculations."), AsString(SQL[1])));
categories.CancelRemove();
}

28 | P a g e

else
{
SQL & Delete(CATEGORIES).Where(ID == categories(ID));
UpdateCategories();
}
}
catch(SqlExc &e)
{
categories.CancelRemove();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::InsertMoney()
{
try
{
SQL & Insert(MONEY)
(DT_ID,

dtid)

(CAT_ID, money(CAT_ID))
(PM,

money(PM))

(VALUE,

money(VALUE))

(DT,

money(DT))

(DESC,

money(DESC));

money(ID) = SQL.GetInsertedId();

UpdateSummary();
}
catch(SqlExc &e)
{
money.CancelInsert();

29 | P a g e

Exclamation("[* " + DeQtfLf(e) + "]");


}
}

void HomeBudget::UpdateMoney()
{
try
{
SQL & ::Update(MONEY)
(DT_ID,

dtid)

(CAT_ID, money(CAT_ID))
(PM,

money(PM))

(VALUE,

money(VALUE))

(DT,

money(DT))

(DESC,

money(DESC))

.Where(ID == money(ID));

UpdateSummary();
}
catch(SqlExc &e)
{
money.CancelUpdate();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::RemoveMoney()
{
try
{
SQL & Delete(MONEY).Where(ID == money(ID));
UpdateSummary();

30 | P a g e

}
catch(SqlExc &e)
{
money.CancelRemove();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::InsertDate()
{
try
{
SQL & Insert(DATES)(DT, month(DT));
month(ID) = dtid = (int) SQL.GetInsertedId();
EnableMoney();
}
catch(SqlExc &e)
{
month.CancelInsert();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::EnableMoney(int cnt)


{
money.Enable(cnt < 0 ? month.GetCount() > 0 : cnt);
}

void HomeBudget::UpdateDate()
{
try
{

31 | P a g e

SQL & ::Update(DATES)(DT, month(DT)).Where(ID == month(ID));


}
catch(SqlExc &e)
{
month.CancelUpdate();
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::RemoveDate()
{
try
{
SQL.Begin();
SQL & Delete(MONEY).Where(DT_ID == month(ID));
SQL & Delete(DATES).Where(ID == month(ID));
SQL.Commit();
bool en = month.GetCount() <= 1 ? false : true;
EnableMoney(en);
if(!en)
money.Clear();
}
catch(SqlExc &e)
{
SQL.Rollback();
month.CancelRemove();
Exclamation("[* " + DeQtfLf(e) + "]");
}

void HomeBudget::ChangeDate()

32 | P a g e

{
dtid = month(ID);
LoadMoney(dtid);
EnableMoney();
UpdateSummary();
GenMonthList(((Date) month(DT)).year);
}

void HomeBudget::NewDate()
{
money.Clear();
money.Disable();
UpdateSummary();
}

void HomeBudget::AcceptedDate()
{
if(!month.IsNewRow())
return;

Sql q;
SQL.Begin();
SQL * Select(ID, DEFVALUE, PM).From(CATEGORIES).Where(INNEWMONTH == 1);
while(SQL.Fetch())
{
money.Add();
money(CAT_ID) = SQL[ID];
money(VALUE) = SQL[DEFVALUE];
money(PM) = SQL[PM];

q * Insert(MONEY)
(DT_ID,

33 | P a g e

dtid)

(CAT_ID, money(CAT_ID))
(PM,

money(PM))

(VALUE,

money(VALUE))

(DT,

money(DT))

(DESC,

money(DESC));

money(ID) = SQL.GetInsertedId();

money.RefreshNewRow();
}
SQL.Commit();
UpdateSummary();
}

void HomeBudget::UpdateSummary()
{
if(!month.IsCursor())
return;

float p = 0, tp = 0;
float m = 0, tm = 0;
float r = 0, tr = 0;

mostcat.Clear();
mostpr.Clear();

try
{
SQL & Select(PM, SqlSum(VALUE))
.From(MONEY, DATES)
.Where(DT.Of(DATES) < month(DT) && DT_ID == ID.Of(DATES) && NotNull(VALUE))
.GroupBy(PM);

34 | P a g e

while(SQL.Fetch())
{
int pm = SQL[PM];
float v = (float) int(SQL[1]);
if(pm < 0)
tm = v;
else
tp = v;
}

tr = tp - tm;

SQL & Select(PM, SqlSum(VALUE))


.From(MONEY)
.Where(DT_ID == dtid && NotNull(VALUE))
.GroupBy(PM);

while(SQL.Fetch())
{
int pm = SQL[PM];
float v = (float) int(SQL[1]);
if(pm < 0)
m = v;
else
p = v;
}

SQL & Select(NAME, SqlId("sum(value) as val"))


.From(MONEY, CATEGORIES)
.Where(DT_ID == dtid && CAT_ID == ID.Of(CATEGORIES) && PM.Of(MONEY) < 0)
.GroupBy(CAT_ID)

35 | P a g e

.OrderBy(Descending(SqlId("val")));

while(SQL.Fetch())
mostpr.Add(SQL);

SQL & Select(NAME.Of(GROUPS), SqlId("sum(value) as val"))


.From(MONEY, GROUPS, CATEGORIES)
.Where(DT_ID == dtid && PM.Of(MONEY) < 0 && CAT_ID == ID.Of(CATEGORIES) &&
GR_ID == ID.Of(GROUPS))
.GroupBy(GR_ID)
.OrderBy(Descending(SqlId("val")));

while(SQL.Fetch())
mostcat.Add(SQL);
}
catch(SqlExc &e)
{
Exclamation("[* " + DeQtfLf(e) + "]");
}

r = p - m;
plus.SetText(Format("%.2f", p));
minus.SetText(Format("%.2f", m));
SetRest(rest, r);
SetRest(prev_month, tr);
SetRest(real_rest, r + tr);
}

void HomeBudget::ClearSummary()
{
plus.SetText("");
minus.SetText("");

36 | P a g e

rest.SetText("");
prev_month.SetText("");
real_rest.SetText("");
mostpr.Clear();
mostcat.Clear();
}

void HomeBudget::SetRest(StaticText &rest, float r)


{
if(r == 0)
{
rest.SetText("0.00");
rest.SetInk(Black);
}
else if(r > 0)
{
rest.SetText(Format("+%.2f", r));
rest.SetInk(Green);
}
else
{
rest.SetText(Format("%.2f", r));
rest.SetInk(LtRed);
}
}

void HomeBudget::UpdateValue()
{
if(money.IsEmpty())
return;

try

37 | P a g e

{
SQL & Select(DEFVALUE, PM).From(CATEGORIES).Where(ID == money.Get(CAT_ID));
Value v = SQL.Fetch() ? SQL[0] : Value(0);
Value s = SQL.Fetch() ? SQL[1] : Value(-1);

if(IsNull(money.Get(VALUE)))
money.Set(VALUE, v);

if(IsNull(money.Get(PM)))
money.Set(PM, s);
}
catch(SqlExc &e)
{
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::Options()
{
WithOptionsLayout<TopWindow> dlg;
CtrlLayoutOK(dlg, t_("Options"));
dlg.lang.Add(0, "English")
.SetIndex(lang);
dlg.clear <<= THISBACK(ClearAll);
if(dlg.Execute() != IDOK)
return;
lang = ~dlg.lang;
}

void HomeBudget::ClearAll()
{
try

38 | P a g e

{
SQL & Delete(CATEGORIES);
SQL & Delete(GROUPS);
SQL & Delete(MONEY);
SQL & Delete(DATES);
//SQL.ExecuteX("VACUUM");

LoadDates();
LoadGroups();
UpdateCategories();
money.Clear();
categories.Clear();
EnableMoney();

PromptOK(t_("Database was cleared"));


}
catch(SqlExc &e)
{
Exclamation("[* " + DeQtfLf(e) + "]");
}
}

void HomeBudget::About()
{
WithAboutLayout<TopWindow> dlg;
CtrlLayoutCancel(dlg, t_("About"));
dlg.info.NoSb();
dlg.info.SetQTF(GetTopic(String("HomeBudget/src/About$") + (lang == 0 ? "enus" : "pl-pl")), Zoom(150, 1200));
dlg.info.SetZoom(Zoom(1, 1));
dlg.Execute();
}

39 | P a g e

void HomeBudget::Help()
{
HomeBudgetHelp dlg;
dlg.AddTree(0, Images::Plus(), "HomeBudget/help/Introduction$en-us",
"Introduction");
dlg.AddTree(0, Images::Plus(), "HomeBudget/help/T0$en-us", "Instruction");
dlg.AddTree(0, Images::Plus(), "HomeBudget/src/About$en-us", "About");
dlg.Execute();

HomeBudgetHelp::HomeBudgetHelp()
{
}

Topic HomeBudgetHelp::AcquireTopic(const String& topic)


{
Topic t;
t = GetTopic(topic);
t.text = (const char *) GetTopic(topic);
//String path = topic;
//if(FileExists(path))
//

t.text = ReadTopic(LoadFile(path)) .text;

return t;
}

GUI_APP_MAIN
{
bool nodb = false;
Sqlite3Session db;
db.LogErrors(true);

40 | P a g e

#ifdef flagDEBUG
db.SetTrace();
nodb = true;
#endif

FileIn fi("HomeBudget.db3");
if(fi.IsError() || fi.GetSize() <= 0)
nodb = true;
fi.Close();

if(!db.Open(ConfigFile("HomeBudget.db3")))
{
Exclamation(t_("Can't create or open database file"));
return;
}

SQL = db;

if(nodb)
{
SqlSchema sch(SQLITE3);
StdStatementExecutor se(db);
All_Tables(sch);
if(sch.ScriptChanged(SqlSchema::UPGRADE))
Sqlite3PerformScript(sch.Upgrade(), se);
if(sch.ScriptChanged(SqlSchema::ATTRIBUTES))
{
Sqlite3PerformScript(sch.Attributes(), se);
}
if(sch.ScriptChanged(SqlSchema::CONFIG))
{

41 | P a g e

Sqlite3PerformScript(sch.ConfigDrop(), se);
Sqlite3PerformScript(sch.Config(), se);
}
sch.SaveNormal();
}

HomeBudget hb;

LoadFromFile(hb);

switch(hb.lang) {

default:
SetLanguage(LNGC_('E','N','U','S', CHARSET_UNICODE));
break;
}
hb.Setup();
hb.Run();
StoreToFile(hb);
}

42 | P a g e

HomeBudget.sch
TABLE_(DATES)
INT_

(ID) PRIMARY_KEY

DATE_

(DT)

END_TABLE

TABLE_(GROUPS)
INT

(ID) PRIMARY_KEY

STRING_ (NAME, 500)


END_TABLE

TABLE_(CATEGORIES)
INT

(ID) PRIMARY_KEY

INT_

(GR_ID) INDEX

STRING

(NAME, 500)

DOUBLE_ (DEFVALUE)
INT_

(PM)

INT_

(INNEWMONTH)

END_TABLE

TABLE_(MONEY)
INT

(ID) PRIMARY_KEY

INT_ (DT_ID) INDEX


INT_ (CAT_ID) INDEX

43 | P a g e

INT

(PM)

DOUBLE_ (VALUE)
DATE (DT)
STRING_ (DESC, 1024)
END_TABLE

HomeBudget.lay
LAYOUT(HomeBudgetLayout, 776, 400)
ITEM(GridCtrl, month, LeftPosZ(4, 124).VSizePosZ(4, 34))
ITEM(TabCtrl, tab, HSizePosZ(132, 4).VSizePosZ(4, 186))
ITEM(Button, about, SetLabel(t_("About")).LeftPosZ(4, 76).BottomPosZ(4, 26))
ITEM(Button, help, SetLabel(t_("Help")).LeftPosZ(84, 76).BottomPosZ(4, 26))
ITEM(Button, options, SetLabel(t_("Options")).LeftPosZ(164, 76).BottomPosZ(4,
26))
ITEM(Button, exit, SetLabel(t_("Exit")).RightPosZ(4, 76).BottomPosZ(6, 26))
ITEM(LabelBox, dv___6, SetLabel(t_("Summary")).HSizePosZ(132,
252).BottomPosZ(34, 148))
ITEM(StaticText, dv___7,
SetText(t_("Income:")).SetFont(StdFontZ(18).Bold()).LeftPosZ(140,
88).BottomPosZ(144, 22))
ITEM(StaticText, plus, SetFont(StdFontZ(18).Bold()).HSizePosZ(260,
376).BottomPosZ(142, 22))
ITEM(StaticText, dv___9,
SetText(t_("Expenditure:")).SetFont(StdFontZ(18).Bold()).LeftPosZ(140,
116).BottomPosZ(118, 24))
ITEM(StaticText, minus, SetFont(StdFontZ(18).Bold()).HSizePosZ(260,
376).BottomPosZ(118, 22))
ITEM(StaticText, rest_label,
SetText(t_("Savings:")).SetFont(StdFontZ(18).Bold()).LeftPosZ(140,
88).BottomPosZ(92, 26))
ITEM(StaticText, rest, SetFont(StdFontZ(18).Bold()).HSizePosZ(260,
376).BottomPosZ(94, 22))
ITEM(StaticText, dv___13, SetText(t_("Amount From Prev.
Month:")).SetFont(StdFontZ(18).Bold()).LeftPosZ(140, 268).BottomPosZ(70, 22))

44 | P a g e

ITEM(StaticText, prev_month, SetFont(StdFontZ(18).Bold()).HSizePosZ(412,


260).BottomPosZ(70, 22))
ITEM(StaticText, dv___15, SetText(t_("Final
Savings:")).SetFont(StdFontZ(18).Bold()).LeftPosZ(140, 268).BottomPosZ(42,
26))
ITEM(StaticText, real_rest, SetFont(StdFontZ(18).Bold()).HSizePosZ(412,
260).BottomPosZ(42, 22))
ITEM(LabelBox, dv___17, SetLabel(t_("Most expensive")).RightPosZ(4,
244).BottomPosZ(34, 148))
ITEM(TabCtrl, tabmost, RightPosZ(8, 232).BottomPosZ(42, 124))
END_LAYOUT

LAYOUT(OptionsLayout, 216, 86)


ITEM(StaticText, dv___0, SetText(t_("Language")).LeftPosZ(4, 60).TopPosZ(4,
18))
ITEM(DropList, lang, LeftPosZ(68, 144).TopPosZ(4, 19))
ITEM(Button, ok, SetLabel(t_("OK")).RightPosZ(4, 74).BottomPosZ(4, 24))
ITEM(Button, clear, SetLabel(t_("Clear all data from database")).RightPosZ(4,
208).BottomPosZ(34, 24))
END_LAYOUT

LAYOUT(AboutLayout, 468, 336)


ITEM(RichTextView, info, SetFrame(BlackFrame()).HSizePosZ(4, 0).TopPosZ(4,
296))
ITEM(StaticText, dv___1, LeftPosZ(108, 228).TopPosZ(84, 92))
ITEM(Button, cancel, SetLabel(t_("OK")).HCenterPosZ(72, -10).TopPosZ(304,
24))
END_LAYOUT

LAYOUT(NewCategoryLayout, 244, 108)


ITEM(StaticText, dv___0, SetText(t_("Category")).LeftPosZ(4, 60).TopPosZ(4,
19))
ITEM(DropList, groups, LeftPosZ(68, 146).TopPosZ(4, 20))
ITEM(Button, addgroup, LeftPosZ(218, 20).TopPosZ(4, 20))
ITEM(StaticText, dv___3, SetText(t_("Name")).LeftPosZ(4, 60).TopPosZ(26, 19))
ITEM(EditString, name, LeftPosZ(68, 172).TopPosZ(26, 19))

45 | P a g e

ITEM(Switch, pm, SetLabel(t_("Plus\nMinus")).LeftPosZ(68, 100).TopPosZ(50,


15))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(88, 74).TopPosZ(80, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(166, 74).TopPosZ(80,
24))
END_LAYOUT

LAYOUT(NewGroupLayout, 204, 56)


ITEM(StaticText, dv___0, SetText(t_("Name")).LeftPosZ(4, 60).TopPosZ(4, 19))
ITEM(EditString, name, LeftPosZ(68, 130).TopPosZ(4, 19))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(48, 74).TopPosZ(28, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(126, 74).TopPosZ(28,
24))
END_LAYOUT

46 | P a g e

CONCLUSION
Our project is only a humble venture to satisfy the needs for
a budgeting software. Several user friendly coding have also
adopted. This package shall prove to be a powerful package
in satisfying all the requirements of an individual.
The objective of software planning is to provide a framework
that enables us to make reasonable estimates made within a
limited time frame at the beginning of the software project
and should be updated regularly as the project progresses.
Last but not least it is not the work that played the ways to
success but ALMIGHTY.

47 | P a g e

Bibliography
Books
1) Charles Petzold's "Programming Windows", Fifth Edition
2) Introduction to Windows and Graphics Programming with
Visual C++

Web Resources
1) www.dreamincode.net
2) www.cplusplus.com
3) www.github.com

48 | P a g e

You might also like