prototyped svg reports
This commit is contained in:
@@ -2,9 +2,14 @@ package reports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"ruben/inventory2/consts"
|
||||
"ruben/inventory2/domains/accounts"
|
||||
"ruben/inventory2/logging"
|
||||
)
|
||||
@@ -30,3 +35,225 @@ func NewStore(logger *logging.Logger, db *pgxpool.Pool, accts *accounts.Store) *
|
||||
func (db *Store) WithContext(ctx context.Context) *StoreWithContext {
|
||||
return NewStoreWithContext(ctx, db)
|
||||
}
|
||||
|
||||
// TODO: prefix all these names with 'mock' since they're all mock stuff
|
||||
|
||||
type (
|
||||
ListingCountsOverTimeReport struct {
|
||||
AccountID int64
|
||||
Platform accounts.Platform
|
||||
ShopID string
|
||||
ListingID string
|
||||
Counts []ListingCountAtTime
|
||||
}
|
||||
|
||||
ListingCountAtTime struct {
|
||||
EventTimestamp *time.Time
|
||||
Count int64
|
||||
}
|
||||
)
|
||||
|
||||
func (r ListingCountsOverTimeReport) MaxCount() ListingCountAtTime {
|
||||
if len(r.Counts) == 0 {
|
||||
return ListingCountAtTime{}
|
||||
}
|
||||
return slices.MaxFunc(r.Counts, func(a, b ListingCountAtTime) int {
|
||||
return int(a.Count - b.Count)
|
||||
})
|
||||
}
|
||||
|
||||
func (r ListingCountsOverTimeReport) MinCount() ListingCountAtTime {
|
||||
if len(r.Counts) == 0 {
|
||||
return ListingCountAtTime{}
|
||||
}
|
||||
return slices.MinFunc(r.Counts, func(a, b ListingCountAtTime) int {
|
||||
return int(a.Count - b.Count)
|
||||
})
|
||||
}
|
||||
|
||||
func (db *Store) GetListingCountsReport(ctx context.Context, acctID int64, platform accounts.Platform, shopID, listingID string) (*ListingCountsOverTimeReport, error) {
|
||||
counts, err := db.GetListingCountsOverTime(ctx, acctID, platform, shopID, listingID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ListingCountsOverTimeReport{
|
||||
AccountID: acctID,
|
||||
Platform: platform,
|
||||
ShopID: shopID,
|
||||
ListingID: listingID,
|
||||
Counts: counts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (db *Store) GetListingCountsOverTime(ctx context.Context, acctID int64, platform accounts.Platform, shopID, listingID string) ([]ListingCountAtTime, error) {
|
||||
info, ok := getMockShopSchemaInfo(platform)
|
||||
if !ok {
|
||||
return nil, consts.ErrNotFound
|
||||
}
|
||||
|
||||
var counts []ListingCountAtTime
|
||||
|
||||
err := pgx.BeginTxFunc(ctx, db.db, pgx.TxOptions{
|
||||
AccessMode: pgx.ReadOnly,
|
||||
}, func(tx pgx.Tx) error {
|
||||
rows, err := tx.Query(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
SELECT
|
||||
1
|
||||
FROM
|
||||
%s
|
||||
WHERE
|
||||
shop_id = @shop_id
|
||||
AND listing_id = @listing_id
|
||||
`,
|
||||
info.listingsTable,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"shop_id": shopID,
|
||||
"listing_id": listingID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query to check the existing of the listing: %w", err)
|
||||
}
|
||||
|
||||
if _, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[int]); err != nil {
|
||||
return fmt.Errorf("listing not found: %w", consts.ErrNotFound)
|
||||
}
|
||||
|
||||
rows, err = tx.Query(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`
|
||||
SELECT
|
||||
event_timestamp AS eventTimestamp,
|
||||
"count"
|
||||
FROM
|
||||
%s
|
||||
WHERE
|
||||
shop_id = @shop_id
|
||||
AND listing_id = @listing_id
|
||||
`,
|
||||
info.listingCountsView,
|
||||
),
|
||||
pgx.NamedArgs{
|
||||
"shop_id": shopID,
|
||||
"listing_id": listingID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
if counts, err = pgx.CollectRows(rows, pgx.RowToStructByNameLax[ListingCountAtTime]); err != nil {
|
||||
return fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return counts, err
|
||||
}
|
||||
|
||||
type mockShopSchemaInfo struct {
|
||||
platform accounts.Platform
|
||||
shopTable string
|
||||
listingsTable string
|
||||
listingCountsView string
|
||||
}
|
||||
|
||||
func getMockShopSchemaInfo(platform accounts.Platform) (mockShopSchemaInfo, bool) {
|
||||
for _, in := range getAllMockShopSchemaInfos() {
|
||||
if in.platform == platform {
|
||||
return in, true
|
||||
}
|
||||
}
|
||||
|
||||
return mockShopSchemaInfo{}, false
|
||||
}
|
||||
|
||||
func getAllMockShopSchemaInfos() []mockShopSchemaInfo {
|
||||
return []mockShopSchemaInfo{
|
||||
{
|
||||
platform: accounts.Amazon,
|
||||
shopTable: "mock.shop_amazon",
|
||||
listingsTable: "mock.shop_amazon_listings",
|
||||
listingCountsView: "mock.shop_amazon_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.BigCartel,
|
||||
shopTable: "mock.shop_big_cartel",
|
||||
listingsTable: "mock.shop_big_cartel_listings",
|
||||
listingCountsView: "mock.shop_big_cartel_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Ebay,
|
||||
shopTable: "mock.shop_ebay",
|
||||
listingsTable: "mock.shop_ebay_listings",
|
||||
listingCountsView: "mock.shop_ebay_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Ecwid,
|
||||
shopTable: "mock.shop_ecwid",
|
||||
listingsTable: "mock.shop_ecwid_listings",
|
||||
listingCountsView: "mock.shop_ecwid_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Etsy,
|
||||
shopTable: "mock.shop_etsy",
|
||||
listingsTable: "mock.shop_etsy_listings",
|
||||
listingCountsView: "mock.shop_etsy_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Shopify,
|
||||
shopTable: "mock.shop_shopify",
|
||||
listingsTable: "mock.shop_shopify_listings",
|
||||
listingCountsView: "mock.shop_shopify_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.SquareOnline,
|
||||
shopTable: "mock.shop_square_online",
|
||||
listingsTable: "mock.shop_square_online_listings",
|
||||
listingCountsView: "mock.shop_square_online_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Squarespace,
|
||||
shopTable: "mock.shop_squarespace",
|
||||
listingsTable: "mock.shop_squarespace_listings",
|
||||
listingCountsView: "mock.shop_squarespace_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Tiktok,
|
||||
shopTable: "mock.shop_tiktok",
|
||||
listingsTable: "mock.shop_tiktok_listings",
|
||||
listingCountsView: "mock.shop_tiktok_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.WalmartMarketplace,
|
||||
shopTable: "mock.shop_walmart_marketplace",
|
||||
listingsTable: "mock.shop_walmart_marketplace_listings",
|
||||
listingCountsView: "mock.shop_walmart_marketplace_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Wix,
|
||||
shopTable: "mock.shop_wix",
|
||||
listingsTable: "mock.shop_wix_listings",
|
||||
listingCountsView: "mock.shop_wix_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.WooCommerce,
|
||||
shopTable: "mock.shop_woo_commerce",
|
||||
listingsTable: "mock.shop_woo_commerce_listings",
|
||||
listingCountsView: "mock.shop_woo_commerce_listing_counts",
|
||||
},
|
||||
{
|
||||
platform: accounts.Zoho,
|
||||
shopTable: "mock.shop_zoho",
|
||||
listingsTable: "mock.shop_zoho_listings",
|
||||
listingCountsView: "mock.shop_zoho_listing_counts",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,3 +23,11 @@ func NewStoreWithContext(ctx context.Context, v *Store) *StoreWithContext {
|
||||
func (v_ctx *StoreWithContext) GetRawShopEvents(acctID int64, platform accounts.Platform, shopID string) ([]RawShopEvent, error) {
|
||||
return v_ctx.Store.GetRawShopEvents(v_ctx.ctx, acctID, platform, shopID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetListingCountsReport(acctID int64, platform accounts.Platform, shopID string, listingID string) (*ListingCountsOverTimeReport, error) {
|
||||
return v_ctx.Store.GetListingCountsReport(v_ctx.ctx, acctID, platform, shopID, listingID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetListingCountsOverTime(acctID int64, platform accounts.Platform, shopID string, listingID string) ([]ListingCountAtTime, error) {
|
||||
return v_ctx.Store.GetListingCountsOverTime(v_ctx.ctx, acctID, platform, shopID, listingID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user