예제 #1
0
async def create_wallet(wallet: WalletIn):
    async with get_connection() as conn:
        resp = await conn.execute_insert(
            'INSERT INTO wallets (name, balance) VALUES (:name, :balance)',
            wallet.dict())
        await conn.commit()
        return resp['last_insert_rowid()']
예제 #2
0
async def update_comment(id: int = Path(...),
                         comment: str = Query(..., min_length=1,
                                              max_length=64)):
    """Commission transaction comments are unmodifiable."""
    async with get_connection() as conn:
        await conn.execute(
            'UPDATE transactions SET comment = ? WHERE rowid = ? AND to_id != ?',
            (comment, id, OUR_WALLET_ID))
        await conn.commit()
예제 #3
0
async def delete_wallet(id: int = Path(..., gt=1)):
    """_Our_ wallet can't be deleted."""
    async with get_connection() as conn:
        try:
            await conn.execute('DELETE FROM wallets WHERE id = ?', (id, ))
            await conn.commit()
        except aiosqlite.IntegrityError as e:
            await conn.rollback()
            logging.exception(e)
            raise HTTPException(409)
예제 #4
0
async def create_transaction(
        transaction: TransactionIn = Body(...),
        cp: CommissionPayer = Body(
            CommissionPayer.sender,
            alias='commission',
            title='who pays commission: sender, receiver or both')):
    transactions = [transaction]
    wallets = []

    if cp == CommissionPayer.both:
        commission = TransactionIn(from_id=transaction.from_id,
                                   to_id=OUR_WALLET_ID,
                                   amount=transaction.amount * COMMISSION / 2,
                                   comment='0.75% commission')
        transactions.append(commission)
        transactions.append(
            commission.copy(update={'from_id': transaction.to_id}))

        delta_amount_f = transaction.amount + commission.amount
        wallets.append((-delta_amount_f, transaction.from_id))
        wallets.append(
            (transaction.amount - commission.amount, transaction.to_id))
        wallets.append((2 * commission.amount, OUR_WALLET_ID))

    elif cp == CommissionPayer.receiver:
        commission = TransactionIn(from_id=transaction.to_id,
                                   to_id=OUR_WALLET_ID,
                                   amount=transaction.amount * COMMISSION,
                                   comment='1.5% commission')
        transactions.append(commission)

        delta_amount_f = transaction.amount
        wallets.append((-delta_amount_f, transaction.from_id))
        wallets.append(
            (transaction.amount - commission.amount, transaction.to_id))
        wallets.append((commission.amount, OUR_WALLET_ID))
    else:
        commission = TransactionIn(from_id=transaction.from_id,
                                   to_id=OUR_WALLET_ID,
                                   amount=transaction.amount * COMMISSION,
                                   comment='1.5% commission')
        transactions.append(commission)

        delta_amount_f = transaction.amount + commission.amount
        wallets.append((-delta_amount_f, transaction.from_id))
        wallets.append((transaction.amount, transaction.to_id))
        wallets.append((commission.amount, OUR_WALLET_ID))

    async with get_connection() as conn:
        try:
            await conn.execute('BEGIN')

            balance = await conn.execute_fetchall(
                'SELECT balance FROM wallets WHERE id = ?',
                (transaction.from_id, ))
            if not balance:
                raise HTTPException(409, 'Invalid wallet')

            if balance[0]['balance'] < delta_amount_f:  # type:ignore
                raise HTTPException(409, 'Insufficent funds')

            for tr in transactions:
                await conn.execute_insert(
                    'INSERT INTO transactions (from_id, to_id, amount, comment) '
                    'VALUES (:from_id, :to_id, :amount, :comment)', tr.dict())
            for wp in wallets:
                await conn.execute_insert(
                    'UPDATE wallets SET balance = balance + ? WHERE id = ?',
                    wp)
            await conn.commit()
        except HTTPException:
            await conn.rollback()
            raise
        except aiosqlite.IntegrityError as e:
            await conn.rollback()
            logging.exception(e)
            raise HTTPException(409, 'Invalid wallet')
예제 #5
0
async def list_transactions(page: int = Query(0, ge=0),
                            size: int = Query(10, gt=0, lte=100)):
    async with get_connection() as conn:
        return await conn.execute_fetchall(
            'SELECT rowid AS id, * FROM transactions ORDER BY created_at DESC '
            'LIMIT ? OFFSET ?', (size, page * size))
예제 #6
0
async def rename_wallet(id: int = Path(...),
                        name: str = Query(..., min_length=1, max_length=64)):
    async with get_connection() as conn:
        await conn.execute('UPDATE wallets SET name = ? WHERE id = ?',
                           (name, id))
        await conn.commit()
예제 #7
0
async def list_wallets():
    async with get_connection() as conn:
        return await conn.execute_fetchall('SELECT * FROM wallets')