aboutsummaryrefslogtreecommitdiff
path: root/jb/managers/thl.py
blob: 191a56bf930edec048b287e95ff71702e5ae7611 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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 (
    CashoutMethodOut,
    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, client_ip: str
) -> str | None:
    """
    Make sure a paypal cashout method exists for this user. Use their login email.
    We check if it exists first, so that once a user can change their paypal email,
        we do not overwrite it.
    """
    url = f"{settings.fsb_host}{settings.product_id}/cashout_methods/"
    params = {"bpuid": product_user_id, "ip": client_ip}
    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, client_ip: str
) -> None:
    if not get_paypal_cashout_method_if_exists(product_user_id, client_ip=client_ip):
        create_paypal_cashout_method(product_user_id, email)


def get_cashout_method(cashout_method_id: str) -> CashoutMethodOut:
    url = (
        f"{settings.fsb_host}{settings.product_id}/cashout_methods/{cashout_method_id}/"
    )
    res = requests.get(url)
    assert res.status_code == status.HTTP_200_OK, res.text
    return CashoutMethodOut.model_validate(res.json()["cashout_method"])


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


def get_cashout_detail(cashout_id: str) -> CashoutRequestInfo:
    url = f"{settings.fsb_host}{settings.product_id}/cashout/{cashout_id}/"
    res = requests.get(url)
    assert res.status_code == status.HTTP_200_OK, res.text
    return CashoutRequestInfo.model_validate(res.json()["cashout"])