···11+from sqlmodel import create_engine
22+33+from kefi.config import settings
44+55+# Creates the engine from the database url, to allow to create a session with
66+# the database
77+engine = create_engine(settings.db_url())
kefi/models/core/__init__.py
This is a binary file and will not be displayed.
+130
kefi/models/core/helpers.py
···11+from slack_sdk import WebClient
22+from sqlmodel import Session, func, or_, select
33+44+from kefi.config import settings
55+from kefi.dependencies import SlashCommandParams
66+from kefi.models.core.database import Transaction, User
77+from kefi.routers.responses import ResetResponse
88+from kefi.slack import Slack
99+1010+1111+def get_or_create_from_command(
1212+ command: SlashCommandParams, session: Session
1313+) -> tuple["User", bool]:
1414+ """Gets or create the user from the given command."""
1515+ query = select(User).filter(User.slack_user_id == command.user_id)
1616+ user = session.exec(query).one_or_none()
1717+ created = not user
1818+ if not user:
1919+ user = User(slack_user_id=command.user_id, slack_username=command.user_name)
2020+ else:
2121+ # Updates the slack username
2222+ user.slack_username = command.user_name
2323+ session.add(user)
2424+ return (user, created)
2525+2626+2727+def available_balance(user: User, session: Session) -> int:
2828+ """Obtains the available balance of the user, that means the balance not spend from
2929+ the monthly received.
3030+ """
3131+ query = select(func.sum(Transaction.amount)).filter( # type: ignore
3232+ Transaction.user == user,
3333+ or_(Transaction.sender == user, Transaction.sender == None), # type: ignore
3434+ )
3535+ return session.exec(query).one() or 0
3636+3737+3838+def received_balance(user: User, session: Session) -> int:
3939+ """Obtains the received balance of the user, that means the balance sent to the
4040+ user.
4141+ """
4242+ query = select(func.sum(Transaction.amount)).filter( # type: ignore
4343+ Transaction.user == user, Transaction.receiver == user
4444+ )
4545+ return session.exec(query).one() or 0
4646+4747+4848+def find_user_by_slack_user_id(slack_user_id: str, session: Session) -> User | None:
4949+ """Gets the user using the Slack user id."""
5050+ query = select(User).filter(User.slack_user_id == slack_user_id)
5151+ return session.exec(query).one_or_none()
5252+5353+5454+def find_user_by_slack_username(slack_username: str, session: Session) -> User | None:
5555+ """Gets the user using the Slack username."""
5656+ query = select(User).filter(User.slack_username == slack_username)
5757+ return session.exec(query).one_or_none()
5858+5959+6060+def create_users(session: Session) -> None:
6161+ """Creates all the users in the team."""
6262+ # Gets the users
6363+ client = WebClient(token=settings.SLACK_BOT_TOKEN)
6464+ response = client.users_list(team_id=settings.SLACK_TEAM_ID)
6565+ members = response["members"]
6666+ while response["response_metadata"]["next_cursor"]:
6767+ response = client.users_list(team_id=settings.SLACK_TEAM_ID)
6868+ members += response["members"]
6969+ members = list(
7070+ filter(lambda user: not user["is_bot"] and not user["deleted"], members)
7171+ )
7272+ # Create or updates the users
7373+ for member in members:
7474+ query = select(User).filter(User.slack_user_id == member["id"])
7575+ user = session.exec(query).one_or_none()
7676+ if not user:
7777+ user = User(
7878+ slack_user_id=member["id"],
7979+ slack_username=member["name"],
8080+ first_name=member["profile"].get("first_name", ""),
8181+ last_name=member["profile"].get("last_name", ""),
8282+ is_admin=member["is_admin"],
8383+ )
8484+ else:
8585+ user.slack_username = member["name"]
8686+ user.is_admin = member["is_admin"]
8787+ user.first_name = member["profile"].get("first_name", "")
8888+ user.last_name = member["profile"].get("last_name", "")
8989+ session.add(user)
9090+9191+9292+def get_all_users(session: Session) -> list["User"]:
9393+ """Gets the complete list of users."""
9494+ return session.exec(select(User)).all()
9595+9696+9797+def send_admin_amount(receiver: User, amount: int, session: Session) -> "Transaction":
9898+ """Creates the transaction needed to send an amount to the receiver."""
9999+ receiver_transaction = Transaction(amount=amount, user=receiver)
100100+ session.add(receiver_transaction)
101101+ return receiver_transaction
102102+103103+104104+def recharge_wallets(amount: int, session: Session) -> None:
105105+ """Recharge all the wallet with the given amount."""
106106+ query = select(User)
107107+ users = session.exec(query).all()
108108+ for user in users:
109109+ transaction = Transaction(amount=amount, user=user)
110110+ session.add(transaction)
111111+112112+113113+def reset_wallets(session: "Session") -> None:
114114+ """Reset the wallets of all the users."""
115115+ users = session.exec(select(User)).all()
116116+ for user in users:
117117+ balance = available_balance(user=user, session=session)
118118+ amount = settings.RECHARGE_KEFIS_AMOUNT - balance
119119+ transaction = Transaction(amount=amount, user=user)
120120+ session.add(transaction)
121121+122122+123123+def notify_reset_wallet(session: Session) -> None:
124124+ """Sends notifications after the wallet was reset."""
125125+ amount = settings.RECHARGE_KEFIS_AMOUNT
126126+ users = session.exec(select(User)).all()
127127+ for user in users:
128128+ slack = Slack()
129129+ response = ResetResponse(amount=amount)
130130+ slack.post_message_user(user.slack_user_id, blocks=response.render()["blocks"])