storj/satellite/satellitedb/billingdb.go
dlamarmorgan 007d4190c2 satellite/{payments/billing,satellitedb}: Add payment billing DB
Add billing DB to the satellite. This DB will hold all transactions on the users account and can be used to compute the users current usable account balance.

Change-Id: I056416efc169e5e5e30c9f30cd8bc766b7bc8073
2022-05-27 08:56:31 +00:00

113 lines
3.2 KiB
Go

// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
package satellitedb
import (
"context"
"github.com/zeebo/errs"
"storj.io/common/uuid"
"storj.io/storj/satellite/payments/billing"
"storj.io/storj/satellite/payments/monetary"
"storj.io/storj/satellite/satellitedb/dbx"
)
// ensures that *billingDB implements billing.TransactionsDB.
var _ billing.TransactionsDB = (*billingDB)(nil)
// billingDB is billing DB.
//
// architecture: Database
type billingDB struct {
db *satelliteDB
}
func (db billingDB) Insert(ctx context.Context, tx billing.Transaction) (err error) {
defer mon.Task()(&ctx)(&err)
return db.db.CreateNoReturn_BillingTransaction(ctx,
dbx.BillingTransaction_TxId([]byte(tx.TXID)),
dbx.BillingTransaction_UserId(tx.AccountID[:]),
dbx.BillingTransaction_Amount(tx.Amount.BaseUnits()),
dbx.BillingTransaction_Currency(tx.Amount.Currency().Symbol()),
dbx.BillingTransaction_Description(tx.Description),
dbx.BillingTransaction_Type(tx.TXType.Int()),
dbx.BillingTransaction_Timestamp(tx.Timestamp))
}
func (db billingDB) List(ctx context.Context, userID uuid.UUID) (txs []billing.Transaction, err error) {
defer mon.Task()(&ctx)(&err)
dbxTXs, err := db.db.All_BillingTransaction_By_UserId_OrderBy_Desc_Timestamp(ctx,
dbx.BillingTransaction_UserId(userID[:]))
if err != nil {
return nil, Error.Wrap(err)
}
for _, dbxTX := range dbxTXs {
tx, err := fromDBXBillingTransaction(dbxTX)
if err != nil {
return nil, Error.Wrap(err)
}
txs = append(txs, *tx)
}
return txs, nil
}
func (db billingDB) ListType(ctx context.Context, userID uuid.UUID, txType billing.TXType) (txs []billing.Transaction, err error) {
defer mon.Task()(&ctx)(&err)
dbxTXs, err := db.db.All_BillingTransaction_By_UserId_And_Type_OrderBy_Desc_Timestamp(ctx,
dbx.BillingTransaction_UserId(userID[:]),
dbx.BillingTransaction_Type(txType.Int()))
if err != nil {
return nil, Error.Wrap(err)
}
for _, dbxTX := range dbxTXs {
tx, err := fromDBXBillingTransaction(dbxTX)
if err != nil {
return nil, Error.Wrap(err)
}
txs = append(txs, *tx)
}
return txs, nil
}
func (db billingDB) ComputeBalance(ctx context.Context, userID uuid.UUID) (_ monetary.Amount, err error) {
defer mon.Task()(&ctx)(&err)
dbxTXs, err := db.db.All_BillingTransaction_By_UserId_OrderBy_Desc_Timestamp(ctx,
dbx.BillingTransaction_UserId(userID[:]))
if err != nil {
return monetary.Amount{}, Error.Wrap(err)
}
var balance int64
for _, dbxTX := range dbxTXs {
if dbxTX.Currency == monetary.USDollars.Symbol() {
balance += dbxTX.Amount
}
}
return monetary.AmountFromBaseUnits(balance, monetary.USDollars), nil
}
// fromDBXBillingTransaction converts *dbx.BillingTransaction to *billing.Transaction.
func fromDBXBillingTransaction(dbxTX *dbx.BillingTransaction) (*billing.Transaction, error) {
userID, err := uuid.FromBytes(dbxTX.UserId)
if err != nil {
return nil, errs.Wrap(err)
}
return &billing.Transaction{
TXID: string(dbxTX.TxId),
AccountID: userID,
Amount: monetary.AmountFromBaseUnits(dbxTX.Amount, monetary.USDollars),
Description: dbxTX.Description,
TXType: billing.TXType(dbxTX.Type),
Timestamp: dbxTX.Timestamp,
CreatedAt: dbxTX.CreatedAt,
}, nil
}