aboutsummaryrefslogtreecommitdiff
path: root/jb/managers/thl.py
blob: 59bd2ab8fe03e363fab789bd5e9c7d04b0af2a62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import requests
from fastapi import HTTPException, status
from generalresearch.currency import USDCent
from generalresearch.models.thl.definitions import PayoutStatus
from generalresearch.models.thl.payout import UserPayoutEvent
from generalresearch.models.thl.task_status import TaskStatusResponse
from generalresearch.models.thl.wallet.cashout_method import (
    CashoutRequestInfo,
    CashoutRequestResponse,
)

from jb.config import settings


def get_task_status(tsid: str) -> TaskStatusResponse | None:
    url = f"{settings.fsb_host}{settings.product_id}/status/{tsid}/"
    d = requests.get(url).json()
    if d.get("msg") == "invalid tsid":
        return None

    return TaskStatusResponse.model_validate(d)


def user_cashout_request(
    product_user_id: str, amount: USDCent, cashout_method_id: str
) -> CashoutRequestInfo:
    assert isinstance(amount, USDCent)
    assert USDCent(0) < amount < USDCent(10_00)
    url = f"{settings.fsb_host}{settings.product_id}/cashout/"

    body: dict[str, str | int] = {
        "bpuid": product_user_id,
        "amount": int(amount),
        "cashout_method_id": cashout_method_id,
    }
    res = requests.post(url, json=body)
    if res.status_code == status.HTTP_400_BAD_REQUEST:
        try:
            message = res.json().get("msg")
        except (ValueError, AttributeError):
            message = None
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=message or "Cashout request failed",
        )
    res.raise_for_status()

    d = res.json()
    return CashoutRequestResponse.model_validate(d).cashout


def manage_pending_cashout(
    cashout_id: str, payout_status: PayoutStatus
) -> UserPayoutEvent:
    url = f"{settings.fsb_host}{settings.fsb_host_private_route}/thl/manage_cashout/"
    body = {
        "payout_id": cashout_id,
        "new_status": payout_status.value,
    }
    res = requests.post(url, json=body)
    d = res.json()

    return UserPayoutEvent.model_validate(d)


def get_paypal_cashout_method_if_exists(product_user_id: str) -> str | None:
    """
    Todo: This does not work right now for new users, in that this endpoint expects the user
        to have IP history or the request made from the client
        (b/c it needs their country to know which tango card are available).
    We don't care about that for paypal, but, it expects it anyways.
    Once a user can change their paypal email, this needs to change to avoid overwriting it
        every time they login.
    """
    url = f"{settings.fsb_host}{settings.product_id}/cashout_methods/"
    params = {"bpuid": product_user_id}
    res = requests.get(url, params=params)
    assert res.status_code == status.HTTP_200_OK, res.text
    cms = res.json()["cashout_methods"]
    res = next(filter(lambda x: x["type"] == "PAYPAL", cms), None)
    if res:
        return res["id"]
    return None


def create_paypal_cashout_method(product_user_id: str, email: str) -> dict:
    url = f"{settings.fsb_host}{settings.product_id}/cashout_methods/"
    body = {"bpuid": product_user_id, "type": "PAYPAL", "email": email}
    res = requests.post(url, json=body)
    assert res.status_code == status.HTTP_200_OK, res.text
    return res.json()["cashout_method"]


def create_paypal_cashout_method_if_not_exists(
    product_user_id: str, email: str
) -> None:
    if not get_paypal_cashout_method_if_exists(product_user_id):
        create_paypal_cashout_method(product_user_id, email)


def get_wallet_balance(amt_worker_id: str) -> USDCent:
    # This will raise an Exception if wallet balance is negative
    url = f"{settings.fsb_host}{settings.product_id}/wallet/"
    params = {"bpuid": amt_worker_id}
    return USDCent(requests.get(url, params=params).json()["wallet"]["amount"])


def get_wallet_balance_if_non_negative(amt_worker_id: str) -> USDCent | None:
    url = f"{settings.fsb_host}{settings.product_id}/wallet/"
    params = {"bpuid": amt_worker_id}
    amt = requests.get(url, params=params).json()["wallet"]["amount"]
    if amt >= 0:
        return USDCent(amt)
    return None