def record(update, context): sms = update.message.text is_expense, amount, is_parsed = False, None, False try: is_expense, amount = parse(sms) spent = "spent" if is_expense else "notSpent" text = f"{spent:>9}: {amount or 'anything'}." is_parsed = True except Exception as e: logging.exception(e) text = f"Unable to record." finally: tags = "" if is_expense: tags = tuple(sorted(tag_message(sms))) text += "\nTAGS\n" + " ".join(f"#{t}" for t in tags) tags = " ".join(Tags) tags = f" {tags} " with db.session() as session: session.add( db.Message( sms=sms, is_expense=is_expense, amount=amount, is_parsed=is_parsed, tags=tags, )) session.commit() context.bot.send_message( chat_id=update.effective_chat.id, text=text, reply_to_message_id=update.message.message_id, )
def record(update, context): sms = update.message.text is_expense, amount, is_parsed, is_debit = False, None, False, False tags = "" try: is_expense, amount = parse(sms) if is_expense: tags = tuple(sorted(tag_message(sms))) if any(t.startswith(TAGS.DEBIT_ACCOUNT) for t in tags): is_debit = True tags = " ".join(tags) tags = f" {tags} " spent = "spent" if is_debit else "notSpent" text = f"{spent:>9}: {amount or 'anything'}." is_parsed = True except Exception as e: # pylint: disable=broad-except logging.exception(e) text = "Unable to record." finally: with db.session() as session: session.add( # pylint: disable=no-member db.Message( sms=sms, is_expense=is_debit, amount=amount, is_parsed=is_parsed, tags=tags, )) session.commit() # pylint: disable=no-member update.message.delete() if is_expense: context.bot.send_message(chat_id=update.effective_chat.id, text=f"{sms}\n===============\n{text}")
def test_expenses_are_recorded(): with db.session() as session: for sms in [ """AX-HDFCBK ALERT:Rs.111.11 spent via Debit Card xx1111 at NETFLIX on Oct 1 1111 11:11PM without PIN/OTP.Not you?Call 11111111111.""", """VK-HDFCBK Rs 1111.11 debited from a/c **1111 on 11-11-11 to VPA 1111111111@okbizaxis(UPI Ref No 111111111111). Not you? Call on 11111111111 to report""", """VD-HDFCMF Your SIP Purchase in Folio 11111111/11 under HDFC Mid-Cap Opportunities Fund-Gr. for Rs. 1,111.11 has been processed at the NAV of 11.111 for 11.111 units .""", """VD-IPRUMF Dear Investor,Your SIP Purchase of Rs.1,111.11 in Folio 11111111/11 - Bluechip Fund - Growth for 11.111 units has been processed for NAV of 11.11 -IPRUMF """, """AD-ICICIB Acct XX111 debited with INR 111,111.11 on 11-Sep-11 & Acct XX111 credited. IMPS: 111111111111. Call 11111111 for dispute or SMS BLOCK 111 to 1111111111""", """JD-SBIINB Your a/c no. XXXXXXXX1111 is credited by Rs.111111.11 on 11-11-11 by a/c linked to mobile 1XXXXXX111-XXXXXXX XXXXXX (IMPS Ref no 111111111111). Download""", """AD-ICICIB Dear Customer, your Acct XX111 has been credited with INR 1,11,111.11 on 11-Sep-11. Info:INF*111111111111*SAL SEPT11. The Avbl Bal is INR 1,11,111.11""", """BW-SCISMS Your A/C XXXXX111111 Credited INR 111.11 on 11/11/11 -Deposit by transfer from Mr. XXXXXXXXXXXXX. Avl Bal INR 1,11,111.11""", """AD-HDFCBK ALERT:You've spent Rs.1111.11 via Debit Card xx1111 at www.hotstar.co on 1111-11-11:11:11:11.Avl Bal Rs.11111.11.Not you?Call 11111111111.""", ]: is_expense, amount = parse(sms) session.add( db.Message( sms=sms, is_expense=is_expense, amount=amount, is_parsed=True, )) session.commit() assert monthly_report() != [] assert weekly_report() != []
def import_walnut_report(path): "Import a walnut report to the database" with open(path, "r") as fl, db.session() as session: for row in csv.reader(fl): try: DATE, TIME, _, AMOUNT, _, EXPENSE, _, _, _ = row created_at = pendulum.from_format(f"{DATE} {TIME}", "DD-MM-YY HH:mm A") except ValueError: continue msg = db.Message( sms="", is_expense=EXPENSE == "Yes", is_imported=True, amount=int(float(AMOUNT.replace(",", ""))), created_at=created_at, ) session.add(msg) # pylint: disable=no-member print(msg.created_at, msg.amount, "imported") session.commit() # pylint: disable=no-member
def monthly_report(): last_5_months = (db.utcnow().subtract(months=5).set(day=1, hour=0, minute=0, second=0)) rows = [] with db.session() as session: for row in (session.query(db.Message) # pylint: disable=no-member .filter( db.Message.is_expense == True, # pylint: disable=singleton-comparison db.Message.amount.isnot(None), db.Message.created_at >= last_5_months, ).group_by(sa.func.extract( "month", db.Message.created_at)).order_by( db.Message.created_at.desc()).with_entities( sa.func.extract("month", db.Message.created_at), sa.func.sum(db.Message.amount), )): rows.append((calendar.month_name[row[0]][:3], row[1])) return rows
def weekly_report(): last_5_weeks = db.utcnow().subtract(days=5 * 7).set(hour=0, minute=0, second=0) rows = [] with db.session() as session: for row in (session.query(db.Message) # pylint: disable=no-member .filter( db.Message.is_expense == True, # pylint: disable=singleton-comparison db.Message.amount.isnot(None), db.Message.created_at >= last_5_weeks, ).group_by(sa.func.extract( "week", db.Message.created_at)).order_by( db.Message.created_at.desc()).with_entities( sa.func.extract("week", db.Message.created_at), sa.func.sum(db.Message.amount), )): rows.append((row[0], row[1])) this_week = max([w for w, _ in rows]) rows = [(f"{w - this_week} week" if w != this_week else "This week", total) for w, total in rows] return rows