diff --git a/.gitignore b/.gitignore index 8a4f8c5..783030a 100644 --- a/.gitignore +++ b/.gitignore @@ -164,4 +164,5 @@ cython_debug/ test_func.py users_backup.json one_off_func.py -*.json \ No newline at end of file +*.json +send_notification.py \ No newline at end of file diff --git a/bot/google_sheet_service.py b/bot/google_sheet_service.py index 75e76da..bb7884a 100644 --- a/bot/google_sheet_service.py +++ b/bot/google_sheet_service.py @@ -5,6 +5,11 @@ import json from bot.error_handler import GoogleSheetError +import datetime as dt +import pytz + +timezone = pytz.timezone("Asia/Singapore") + GOOGLE_JSON = os.getenv("GOOGLE_JSON") google_service = json.loads(GOOGLE_JSON) @@ -98,7 +103,7 @@ def get_sub_dropdown_value(spreadsheet_id, main_value, entry_type): raise GoogleSheetError(message=f"Error with retrieving values for sub dropdown value for entrytype: {entry_type}", extra_info=str(e)) -def update_prev_day(spreadsheet_id, month, first_row, last_row=0): +def update_day_total_sum(spreadsheet_id, month, first_row, last_row=0): month = month.title() try: if last_row == 0: @@ -148,26 +153,25 @@ def create_date(spreadsheet_id, day, month, first_row): raise GoogleSheetError(message=f"Fail to create new day for {day} {month}", extra_info=str(e)) -def create_entry(spreadsheet_id, month, row_tracker, row_data): - entry_type = row_data[0] - price = row_data[1].strip() - remarks = row_data[2].strip() - category = row_data[3].strip() - payment = row_data[4].strip() +def create_entry(spreadsheet_id, month, row_tracker, row_data, backlog_day=None): + entry_type, price, remarks, category, payment = (item.strip() if isinstance(item, str) else item for item in row_data) month = month.title() - - data = [price, remarks, category, payment] - sheet_column_start = "H" + + sheet_column_start = "A" sheet_column_end = "K" if entry_type == EntryType.TRANSPORT: remarks_list = [remark.strip() for remark in remarks.split(",")] - sheet_column_start = "C" - sheet_column_end = "G" data = [price] + remarks_list + [category, payment] + else: + data = [None] * 5 + data + # prepend data + data = [backlog_day] + [None] + data if backlog_day else [None] * 2 + data + body = {"values": [data]} + + # creating the entry in google sheet try: - body = {"values": [data]} range_name = ( f"{month}!{sheet_column_start}{row_tracker}:{sheet_column_end}{row_tracker}" ) @@ -196,89 +200,78 @@ def get_sheet_id_by_title(spreadsheet_id, title_to_find): except Exception as e: raise GoogleSheetError(message=f"Fail to retrieve sheet id by title: {title_to_find}", extra_info=str(e)) +def move_row_down(spreadsheet_id, sheet_id, first_row_to_move, last_row_to_move): + try: + requests = [ + { + "copyPaste": { + "source": { + "sheetId": sheet_id, + "startRowIndex": first_row_to_move - 1, + "endRowIndex": last_row_to_move, + "startColumnIndex": start_column_index, + "endColumnIndex": end_column_index, + }, + "destination": { + "sheetId": sheet_id, + "startRowIndex": first_row_to_move, + "endRowIndex": last_row_to_move + 1, + "startColumnIndex": start_column_index, + "endColumnIndex": end_column_index, + }, + "pasteType": "PASTE_NORMAL", + "pasteOrientation": "NORMAL", + } + } + ] + sheets_api.spreadsheets().batchUpdate( + spreadsheetId=spreadsheet_id, body={"requests": requests} + ).execute() + except Exception as e: + raise GoogleSheetError(message=f"Fail to move existing entry down", extra_info=str(e)) def create_backlog_entry(spreadsheet_id, backlog_day, backlog_month, row_data): - entry_type = row_data[0] - price = row_data[1].strip() - remarks = row_data[2].strip() - category = row_data[3].strip() - payment = row_data[4].strip() backlog_month = backlog_month.title() - try: day_first_entry_index = get_day_first_entry_index( spreadsheet_id, backlog_month, backlog_day ) - row_to_move = int(get_first_row_to_move(spreadsheet_id, backlog_month, backlog_day)) + first_row_to_move = int(get_first_row_to_move(spreadsheet_id, backlog_month, backlog_day)) last_row_to_move = int(get_last_entered_row(spreadsheet_id, backlog_month)) - new_entry_row = row_to_move + new_entry_row = first_row_to_move sheet_id = get_sheet_id_by_title(spreadsheet_id, backlog_month.title()) - if row_to_move is None: - new_entry_row = last_row_to_move + 1 - else: - requests = [ - { - "copyPaste": { - "source": { - "sheetId": sheet_id, - "startRowIndex": row_to_move - 1, - "endRowIndex": last_row_to_move, - "startColumnIndex": start_column_index, - "endColumnIndex": end_column_index, - }, - "destination": { - "sheetId": sheet_id, - "startRowIndex": row_to_move, - "endRowIndex": last_row_to_move + 1, - "startColumnIndex": start_column_index, - "endColumnIndex": end_column_index, - }, - "pasteType": "PASTE_NORMAL", - "pasteOrientation": "NORMAL", - } - } - ] - try: - sheets_api.spreadsheets().batchUpdate( - spreadsheetId=spreadsheet_id, body={"requests": requests} - ).execute() - - clear_range = f"{backlog_month}!A{new_entry_row}:K{new_entry_row}" - sheets_api.spreadsheets().values().clear( - spreadsheetId=spreadsheet_id, range=clear_range - ).execute() - - update_prev_day(spreadsheet_id, backlog_month, day_first_entry_index, new_entry_row) - except GoogleSheetError as e: - raise e - except Exception as e: - raise GoogleSheetError(message=f"Fail to move existing entry down", extra_info=str(e)) + if last_row_to_move >= first_row_to_move: + move_row_down(spreadsheet_id, sheet_id, first_row_to_move, last_row_to_move) + clear_range = f"{backlog_month}!A{new_entry_row}:K{new_entry_row}" + sheets_api.spreadsheets().values().clear( + spreadsheetId=spreadsheet_id, range=clear_range + ).execute() + # If there is no entry for the day, create a new date if day_first_entry_index is None: - create_date(spreadsheet_id, backlog_day, backlog_month, new_entry_row) + create_entry(spreadsheet_id, backlog_month, new_entry_row, row_data, backlog_day) day_first_entry_index = new_entry_row - data = [price, remarks, category, payment] - sheet_column_start = "H" - sheet_column_end = "K" - if entry_type == EntryType.TRANSPORT: - remarks_list = [remark.strip() for remark in remarks.split(",")] - sheet_column_start = "C" - sheet_column_end = "G" - data = [price] + remarks_list + [category, payment] + else: + # Create the new entry in the new entry row and update day total + create_entry(spreadsheet_id, backlog_month, new_entry_row, row_data) + update_day_total_sum(spreadsheet_id, backlog_month, day_first_entry_index, new_entry_row) + + # datatime data + current_datetime = dt.datetime.now(timezone) + month = current_datetime.strftime("%b") + + # if backlog month is current month, need to update tracker to reflect backlog changes + if backlog_month.title() == month: + if last_row_to_move < first_row_to_move and day_first_entry_index == new_entry_row: + update_tracker_values(spreadsheet_id, backlog_day, new_entry_row-1, new_entry_row) + if last_row_to_move < first_row_to_move: + row_incremental(spreadsheet_id, EntryType.OTHERS) + else: + row_incremental_all(spreadsheet_id) + - try: - body = {"values": [data]} - range_name = f"{backlog_month}!{sheet_column_start}{new_entry_row}:{sheet_column_end}{new_entry_row}" - sheets_api.spreadsheets().values().update( - spreadsheetId=spreadsheet_id, - range=range_name, - valueInputOption="USER_ENTERED", - body=body, - ).execute() - except Exception as e: - raise GoogleSheetError(message=f"Fail to create backlog entry", extra_info=str(e)) except GoogleSheetError as e: raise e except Exception as e: diff --git a/bot/sheet_service/sheets_services.py b/bot/sheet_service/sheets_services.py index 82648a7..3612d38 100644 --- a/bot/sheet_service/sheets_services.py +++ b/bot/sheet_service/sheets_services.py @@ -164,8 +164,7 @@ def get_last_entered_row(self, spreadsheet_id, month): values = result.get("values", []) return len(values) - # to be rename as update_prev_day_total - def update_prev_day(self, spreadsheet_id, month, first_row, last_row=0): + def update_day_total_sum(self, spreadsheet_id, month, first_row, last_row=0): """ This method update the total amount spend for the previous day """ diff --git a/bot/telegram_bot.py b/bot/telegram_bot.py index 5a3c77a..de918c3 100644 --- a/bot/telegram_bot.py +++ b/bot/telegram_bot.py @@ -105,7 +105,7 @@ def set_up(update, context) -> int: prev_month = (current_datetime - dt.timedelta(days=1)).strftime( "%b" ) - gs.update_prev_day(sheet_id, prev_month, first_row) + gs.update_day_total_sum(sheet_id, prev_month, first_row) new_row = gs.get_last_entered_row(sheet_id, month) first_row = new_row + 1 gs.update_tracker_values(sheet_id, day, new_row, first_row) @@ -581,7 +581,7 @@ def log_transaction(user_data, update): prev_month = (current_datetime - dt.timedelta(days=1)).strftime("%b") # update prev day msg = f"{msg}\nCreating sum for day {day_tracker}" - gs.update_prev_day(sheet_id, prev_month, first_row) + gs.update_day_total_sum(sheet_id, prev_month, first_row) if day == 1 | day < day_tracker: new_row = 4 first_row = 5 @@ -624,15 +624,8 @@ def backlog_transaction(user_data, update): backlog_day = user_data["backlog_day"] backlog_month = user_data["backlog_month"] - # datatime data - current_datetime = dt.datetime.now(timezone) - month = current_datetime.strftime("%b") try: - # if backlog month is current month, need to move all one down - if backlog_month.title() == month: - gs.row_incremental_all(sheet_id) - # user input data entry_type = user_data["entry_type"] payment = user_data["payment"] @@ -643,6 +636,7 @@ def backlog_transaction(user_data, update): # create backlog entry gs.create_backlog_entry(sheet_id, backlog_day, backlog_month, row_data) + except GoogleSheetError as e: raise e except Exception as e: diff --git a/dev_testfunction.py b/dev_testfunction.py new file mode 100644 index 0000000..75ac0ae --- /dev/null +++ b/dev_testfunction.py @@ -0,0 +1,8 @@ +import os +from bot.telegram_bot import * +from bot.database_service.firestore_service import FirestoreService +from bot.google_sheet_service import * +from bot.common import EntryType +db = FirestoreService() + +# Function to test here \ No newline at end of file diff --git a/release_notes.md b/release_notes.md index 0664769..726fecf 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,4 +1,11 @@ # Release Notes +## Version 2.4.2 - Date 14 May 2024 +### Bug Fix 🛠️ +- Fix bug for backlog entry when backlog date doesn't exist + +### For Developer 🧑‍💻 +- Added new dev_testfunction to quickly test and debug functions + ## Version 2.4.1.2 - Date 12 May 2024 ### Bug Fix 🛠️ - Error handling for `/notifyall` command