Ejemplo n.º 1
0
    def update_recipe(self, recipe_id):
        """
        Updates recipe in DB and refreshes page
        :param recipe_id: (int) ID of recipe stored in DB
        :return: None
        """
        validated_data = self.validate_input()
        if validated_data:
            cfg.db_execute(
                sql='''UPDATE recipes SET title=?, `desc`=? WHERE id=?;''',
                variables=(validated_data[0], validated_data[1], recipe_id))
            query = self.parent.search.get()
            if query == 'search...':
                self.parent.refresh_frame()
            else:
                self.parent.refresh_frame(query)

            if self.parent.list.exists(recipe_id):
                self.parent.list.selection_set(recipe_id)
                self.parent.list.focus_set()
                self.parent.list.focus(recipe_id)
            else:
                self.parent.deactivate_buttons()
            self.parent.show_frame(int(recipe_id))
            self.destroy()
Ejemplo n.º 2
0
 def delete_revenue(self, revenue_id):
     """
     Deletes revenue from DB and refreshes trees elements
     :param revenue_id: (int) ID of revenue stored in DB
     :return: None
     """
     cfg.db_execute(sql='''DELETE FROM revenues WHERE id=?;''',
                    variables=(revenue_id, ))
     self.parent.refresh_frame()
     self.destroy()
Ejemplo n.º 3
0
 def add_revenue(self, revenue_type):
     """
     Adds new revenue to DB and refreshes trees elements
     :param revenue_type: (str) type of revenue (income, expense)
     :return: None
     """
     validated_data = self.validate_input()
     if validated_data:
         cfg.db_execute(
             sql='''INSERT INTO revenues VALUES (NULL, ?, ?, ?, ?, ?);''',
             variables=(validated_data[0], revenue_type, validated_data[1],
                        validated_data[2], cfg.CURRENT_USER['id']))
         self.parent.refresh_frame()
         self.destroy()
Ejemplo n.º 4
0
 def update_revenue(self, revenue_id):
     """
     Updates revenue selected by user and refreshes trees elements
     :param revenue_id: (int) ID of revenue stored in DB
     :return: None
     """
     validated_data = self.validate_input()
     if validated_data:
         cfg.db_execute(sql='''UPDATE revenues 
                               SET name=?, amount=?, create_date=? 
                               WHERE id=?;''',
                        variables=(validated_data[0], validated_data[1],
                                   validated_data[2], revenue_id))
         self.parent.refresh_frame()
         self.destroy()
Ejemplo n.º 5
0
 def authenticate(self):
     """
     Validate user input, authenticate user and saves his details to CURRENT_USER global variable
     :return: None
     """
     # VALIDATES USERNAME
     username = self.username_val.get()
     if not username:
         cfg.ValidationError(self,
                             text='Username can\'t be empty!',
                             padx=10,
                             pady=10)
         return
     user = cfg.db_execute(sql='''SELECT * FROM users WHERE username=?;''',
                           variables=(username, ),
                           cursor_type='fetchone')
     if user is None:
         cfg.ValidationError(self,
                             text='Incorrect username or password!',
                             padx=10,
                             pady=10)
         return
     # todo hash password
     # VALIDATES PASSWORD
     password = self.password_val.get()
     if not password or password != user['password']:
         cfg.ValidationError(self,
                             text='Incorrect username or password!',
                             padx=10,
                             pady=10)
         return
     # LOGS USER
     self.parent.login({'id': user['id'], 'username': user['username']})
     self.destroy()
Ejemplo n.º 6
0
 def delete_recipe(self, recipe_id):
     """
     Deletes recipe from DB and refreshes tree elements
     :param recipe_id: (int) ID of recipe stored in DB
     :return: None
     """
     cfg.db_execute(sql='''DELETE FROM recipes WHERE id=?;''',
                    variables=(recipe_id, ))
     query = self.parent.search.get()
     if query == 'search...':
         self.parent.refresh_frame()
     else:
         self.parent.refresh_frame(query)
     self.parent.show_frame(0)
     self.parent.deactivate_buttons()
     self.destroy()
Ejemplo n.º 7
0
    def add_recipe(self):
        """
        Adds new recipe to DB and refreshes page
        :return: None
        """
        validated_data = self.validate_input()
        if validated_data:
            recipe_id = cfg.db_execute(
                sql='''INSERT INTO recipes VALUES (NULL, ?, ?, ?);''',
                variables=(validated_data[0], validated_data[1],
                           cfg.CURRENT_USER['id']),
                cursor_type='last_id')
            query = self.parent.search.get()
            if query == 'search...':
                self.parent.refresh_frame()
            else:
                self.parent.refresh_frame(query)

            if self.parent.list.exists(str(recipe_id)):
                self.parent.list.selection_set(str(recipe_id))
                self.parent.list.focus_set()
                self.parent.list.focus(str(recipe_id))
                self.parent.activate_buttons()
            else:
                self.parent.deactivate_buttons()

            self.parent.show_frame(recipe_id)
            self.destroy()
Ejemplo n.º 8
0
    def refresh_frame(self):
        """
        Refreshes budget page data, deactivates buttons, inserts correct values to trees and sets actual balance
        :return: None
        """
        # CLEARS TREE
        self.exp_tree.delete(*self.exp_tree.get_children())
        self.inc_tree.delete(*self.inc_tree.get_children())
        self.deactivate_buttons()
        # RETRIEVES AND ADDS ACTUAL ELEMENTS TO TREES
        revenues = cfg.db_execute(sql='''SELECT * FROM revenues 
                                         WHERE user_id=?
                                         ORDER BY create_date DESC, amount DESC;''',
                                  variables=(cfg.CURRENT_USER['id'], ))
        for revenue in revenues:
            if revenue['revenue_type'] == 'expense':
                self.exp_tree.insert('',
                                     'end',
                                     values=(revenue['id'], revenue['name'],
                                             '{:.2f}'.format(
                                                 revenue['amount']),
                                             revenue['create_date']))
            else:
                self.inc_tree.insert('',
                                     'end',
                                     values=(revenue['id'], revenue['name'],
                                             '{:.2f}'.format(
                                                 revenue['amount']),
                                             revenue['create_date']))
        # SETS ACTUAL BALANCE

        self.balance_label['text'] = 'Current balance: {:.2f}'.format(
            BudgetFrame.get_balance())
Ejemplo n.º 9
0
 def refresh_frame(self, query=None):
     """
     Refreshes cook book page data, inserts correct values to list tree
     :param query: (str) data passed by user to filter list tree
     :return: None
     """
     # CLEARS FRAMES DICT AND LIST ELEMENTS
     self.frames.clear()
     self.list.delete(*self.list.get_children())
     if query:
         recipes = cfg.db_execute(sql='''SELECT * FROM recipes 
                    WHERE title LIKE ? AND user_id=?
                    ORDER BY title COLLATE NOCASE ASC;''',
                                  variables=('%' + query + '%',
                                             cfg.CURRENT_USER['id']))
     else:
         recipes = cfg.db_execute(sql='''SELECT * FROM recipes 
                    WHERE user_id=?
                    ORDER BY title COLLATE NOCASE ASC;''',
                                  variables=(cfg.CURRENT_USER['id'], ))
     # CREATES WELCOME FRAME
     recipes.append({
         'id':
         0,
         'title':
         'Choose recipe',
         'desc':
         'To see details choose one of available recipes from list on the left'
     })
     # CREATES FRAMES FROM DATA FOUNDED IN DB
     for recipe in recipes:
         frame = Recipe(self.recipe,
                        self,
                        title=recipe['title'],
                        desc=recipe['desc'])
         frame.grid(row=0, column=0, sticky='nsew')
         self.frames[recipe['id']] = frame
     # ADDS ELEMENT TO LIST
     for recipe in recipes:
         if recipe['id'] == 0:
             continue
         self.list.insert('',
                          'end',
                          iid=recipe['id'],
                          values=(recipe['title'].capitalize(),
                                  recipe['desc']))
Ejemplo n.º 10
0
 def get_balance():
     budget = cfg.db_execute(
         sql=
         '''SELECT IFNULL(SUM(CASE WHEN revenue_type='income' THEN amount ELSE 0 END) - 
                              SUM(CASE WHEN revenue_type='expense' THEN amount ELSE 0 END), 0) AS balance
                FROM revenues
                WHERE user_id=?;''',
         variables=(cfg.CURRENT_USER['id'], ))
     return budget[0]['balance']
Ejemplo n.º 11
0
 def create_user(self):
     """
     Saves user to DB and logs by saving user details to CURRENT_USER global variable
     :return: None
     """
     user = self.validate_input()
     # todo hash password
     if user:
         user_id = cfg.db_execute(
             sql='''INSERT INTO users VALUES (NULL, ?, ?);''',
             variables=(user[0], user[1]),
             cursor_type='lastrowid')
         # LOGS USER
         self.parent.login({'id': user_id, 'username': user[0]})
         self.destroy()
Ejemplo n.º 12
0
    def export_to_csv():
        """
        Creates and saves csv file in selected by user directory, open file with default system application
        :return: None
        """
        # SHOWS ASK FOR DIRECTORY WINDOW
        file_dir = filedialog.asksaveasfilename(
            initialdir='/',
            title='Select file',
            filetypes=(('csv file', '*.csv'), ('all files', '*.*')))
        if not file_dir:
            return

        # CREATES FILE IN SELECTED DIRECTORY
        with open(file_dir, 'w', encoding='utf-8') as csv_file:

            field_names = ['name', 'revenue_type', 'amount', 'create_date']
            writer = csv.DictWriter(csv_file, fieldnames=field_names)
            writer.writeheader()

            # FINDS DATA STORED IN DB
            revenues = cfg.db_execute(
                sql='''SELECT name, revenue_type, amount, create_date 
                                             FROM revenues
                                             WHERE user_id=?;''',
                variables=(cfg.CURRENT_USER['id'], ))

            # SAVES DATA IN FILE
            for revenue in revenues:
                writer.writerow(revenue)
            writer.writerow({
                'name': '',
                'revenue_type': 'SUM',
                'amount': BudgetFrame.get_balance(),
                'create_date': ''
            })

        # OPENS SAVED FILE IN DEFAULT SYSTEM APPLICATION
        if sys.platform.startswith('darwin'):
            subprocess.call(('open', file_dir))
        # FOR WINDOWS
        elif os.name == 'nt':
            os.startfile(file_dir)
            return
        # FOR UNIX
        elif os.name == 'posix':
            subprocess.call(('xdg-open', file_dir))
Ejemplo n.º 13
0
 def validate_input(self):
     """
     Validate user input
     :return: tuple containing validated data, None if data was incorrect
     """
     # VALIDATES USERNAME
     username = self.username_val.get()
     if not username:
         cfg.ValidationError(self,
                             text='Username can\'t be empty!',
                             padx=10,
                             pady=10)
         return
     users = cfg.db_execute(
         sql='''SELECT username FROM users WHERE username=?;''',
         variables=(username, ))
     if users:
         cfg.ValidationError(self,
                             text='Username is occupied by another user',
                             padx=10,
                             pady=10)
         return
     # VALIDATES PASSWORDS
     password = self.password_val.get()
     password_conf = self.password_conf_val.get()
     if not password:
         cfg.ValidationError(self,
                             text='Password can\'t be empty!',
                             padx=10,
                             pady=10)
         return
     if password != password_conf:
         cfg.ValidationError(self,
                             text='Passwords do not match!',
                             padx=10,
                             pady=10)
         return
     return username, password