164 lines
5.1 KiB
Go
164 lines
5.1 KiB
Go
|
// Copyright (C) 2019 Storj Labs, Inc.
|
||
|
// See LICENSE for copying information.
|
||
|
|
||
|
package satellitedb
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"database/sql"
|
||
|
"time"
|
||
|
|
||
|
"github.com/skyrings/skyring-common/tools/uuid"
|
||
|
"github.com/zeebo/errs"
|
||
|
|
||
|
"storj.io/storj/satellite/payments/stripecoinpayments"
|
||
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
||
|
)
|
||
|
|
||
|
// ensure that invoiceProjectRecords implements stripecoinpayments.ProjectRecordsDB.
|
||
|
var _ stripecoinpayments.ProjectRecordsDB = (*invoiceProjectRecords)(nil)
|
||
|
|
||
|
// invoiceProjectRecordState defines states of the invoice project record.
|
||
|
type invoiceProjectRecordState int
|
||
|
|
||
|
const (
|
||
|
// invoice project record is not yet applied to customer invoice.
|
||
|
invoiceProjectRecordStateUnapplied invoiceProjectRecordState = 0
|
||
|
// invoice project record has been used during creating customer invoice.
|
||
|
invoiceProjectRecordStateConsumed invoiceProjectRecordState = 1
|
||
|
)
|
||
|
|
||
|
// Int returns intent state as int.
|
||
|
func (intent invoiceProjectRecordState) Int() int {
|
||
|
return int(intent)
|
||
|
}
|
||
|
|
||
|
// invoiceProjectRecords is stripecoinpayments project records DB.
|
||
|
//
|
||
|
// architecture: Database
|
||
|
type invoiceProjectRecords struct {
|
||
|
db *dbx.DB
|
||
|
}
|
||
|
|
||
|
// Create creates new invoice project record in the DB.
|
||
|
func (db *invoiceProjectRecords) Create(ctx context.Context, records []stripecoinpayments.CreateProjectRecord, start, end time.Time) (err error) {
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
return db.db.WithTx(ctx, func(ctx context.Context, tx *dbx.Tx) error {
|
||
|
for _, record := range records {
|
||
|
id, err := uuid.New()
|
||
|
if err != nil {
|
||
|
return Error.Wrap(err)
|
||
|
}
|
||
|
|
||
|
_, err = db.db.Create_StripecoinpaymentsInvoiceProjectRecord(ctx,
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Id(id[:]),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_ProjectId(record.ProjectID[:]),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Storage(record.Storage),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Egress(record.Egress),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Objects(record.Objects),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_PeriodStart(start),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_PeriodEnd(end),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_State(invoiceProjectRecordStateUnapplied.Int()),
|
||
|
)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// Check checks if invoice project record for specified project and billing period exists.
|
||
|
func (db *invoiceProjectRecords) Check(ctx context.Context, projectID uuid.UUID, start, end time.Time) (err error) {
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
_, err = db.db.Get_StripecoinpaymentsInvoiceProjectRecord_By_ProjectId_And_PeriodStart_And_PeriodEnd(ctx,
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_ProjectId(projectID[:]),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_PeriodStart(start),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_PeriodEnd(end),
|
||
|
)
|
||
|
|
||
|
if err != nil {
|
||
|
if err == sql.ErrNoRows {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return stripecoinpayments.ErrProjectRecordExists
|
||
|
}
|
||
|
|
||
|
// Consume consumes invoice project record.
|
||
|
func (db *invoiceProjectRecords) Consume(ctx context.Context, id uuid.UUID) (err error) {
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
_, err = db.db.Update_StripecoinpaymentsInvoiceProjectRecord_By_Id(ctx,
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Id(id[:]),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_Update_Fields{
|
||
|
State: dbx.StripecoinpaymentsInvoiceProjectRecord_State(invoiceProjectRecordStateConsumed.Int()),
|
||
|
},
|
||
|
)
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// ListUnapplied returns project records page with unapplied project records.
|
||
|
func (db *invoiceProjectRecords) ListUnapplied(ctx context.Context, offset int64, limit int, before time.Time) (_ stripecoinpayments.ProjectRecordsPage, err error) {
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
var page stripecoinpayments.ProjectRecordsPage
|
||
|
|
||
|
dbxRecords, err := db.db.Limited_StripecoinpaymentsInvoiceProjectRecord_By_CreatedAt_LessOrEqual_And_State_OrderBy_Desc_CreatedAt(ctx,
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_CreatedAt(before),
|
||
|
dbx.StripecoinpaymentsInvoiceProjectRecord_State(invoiceProjectRecordStateUnapplied.Int()),
|
||
|
limit+1,
|
||
|
offset,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return stripecoinpayments.ProjectRecordsPage{}, err
|
||
|
}
|
||
|
|
||
|
if len(dbxRecords) == limit+1 {
|
||
|
page.Next = true
|
||
|
page.NextOffset = offset + int64(limit) + 1
|
||
|
|
||
|
dbxRecords = dbxRecords[:len(dbxRecords)-1]
|
||
|
}
|
||
|
|
||
|
for _, dbxRecord := range dbxRecords {
|
||
|
record, err := fromDBXInvoiceProjectRecord(dbxRecord)
|
||
|
if err != nil {
|
||
|
return stripecoinpayments.ProjectRecordsPage{}, err
|
||
|
}
|
||
|
|
||
|
page.Records = append(page.Records, *record)
|
||
|
}
|
||
|
|
||
|
return page, nil
|
||
|
}
|
||
|
|
||
|
// fromDBXInvoiceProjectRecord converts *dbx.StripecoinpaymentsInvoiceProjectRecord to *stripecoinpayments.ProjectRecord
|
||
|
func fromDBXInvoiceProjectRecord(dbxRecord *dbx.StripecoinpaymentsInvoiceProjectRecord) (*stripecoinpayments.ProjectRecord, error) {
|
||
|
id, err := bytesToUUID(dbxRecord.Id)
|
||
|
if err != nil {
|
||
|
return nil, errs.Wrap(err)
|
||
|
}
|
||
|
projectID, err := bytesToUUID(dbxRecord.ProjectId)
|
||
|
if err != nil {
|
||
|
return nil, errs.Wrap(err)
|
||
|
}
|
||
|
|
||
|
return &stripecoinpayments.ProjectRecord{
|
||
|
ID: id,
|
||
|
ProjectID: projectID,
|
||
|
Storage: dbxRecord.Storage,
|
||
|
Egress: dbxRecord.Egress,
|
||
|
Objects: dbxRecord.Objects,
|
||
|
PeriodStart: dbxRecord.PeriodStart,
|
||
|
PeriodEnd: dbxRecord.PeriodEnd,
|
||
|
}, nil
|
||
|
}
|