Compare commits
11
Commits
9f86b8e95c
...
f5a3d2594d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5a3d2594d | ||
|
|
987386ea87 | ||
|
|
df1b93261f | ||
|
|
4386ede68e | ||
|
|
c115ab8774 | ||
|
|
b6c652bbf9 | ||
|
|
6945669e51 | ||
|
|
ef7bd051fe | ||
|
|
1330d6efe2 | ||
|
|
10e0261fd2 | ||
|
|
d4348b3ba9 |
@@ -1,4 +1,4 @@
|
||||
# V2 - Attempt 2
|
||||
# V2 - Attempt 2 
|
||||
|
||||
|
||||
# Roadmap
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
BEGIN;
|
||||
|
||||
|
||||
--- event processing
|
||||
|
||||
DROP TRIGGER amazon_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_amazon_event;
|
||||
|
||||
DROP TRIGGER big_cartel_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_big_cartel_event;
|
||||
|
||||
DROP TRIGGER ebay_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_ebay_event;
|
||||
|
||||
DROP TRIGGER ecwid_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_ecwid_event;
|
||||
|
||||
DROP TRIGGER etsy_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_etsy_event;
|
||||
|
||||
DROP TRIGGER shopify_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_shopify_event;
|
||||
|
||||
DROP TRIGGER square_online_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_square_online_event;
|
||||
|
||||
DROP TRIGGER squarespace_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_squarespace_event;
|
||||
|
||||
DROP TRIGGER tiktok_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_tiktok_event;
|
||||
|
||||
DROP TRIGGER walmart_marketplace_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_walmart_marketplace_event;
|
||||
|
||||
DROP TRIGGER wix_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_wix_event;
|
||||
|
||||
DROP TRIGGER woo_commerce_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_woo_commerce_event;
|
||||
|
||||
DROP TRIGGER zoho_store_events ON mock.raw_shop_events;
|
||||
DROP FUNCTION mock.process_raw_zoho_event;
|
||||
|
||||
-- event tables
|
||||
|
||||
DROP TABLE mock.shop_amazon_events;
|
||||
DROP TABLE mock.shop_big_cartel_events;
|
||||
DROP TABLE mock.shop_ebay_events;
|
||||
DROP TABLE mock.shop_ecwid_events;
|
||||
DROP TABLE mock.shop_etsy_events;
|
||||
DROP TABLE mock.shop_shopify_events;
|
||||
DROP TABLE mock.shop_square_online_events;
|
||||
DROP TABLE mock.shop_squarespace_events;
|
||||
DROP TABLE mock.shop_tiktok_events;
|
||||
DROP TABLE mock.shop_walmart_marketplace_events;
|
||||
DROP TABLE mock.shop_wix_events;
|
||||
DROP TABLE mock.shop_woo_commerce_events;
|
||||
DROP TABLE mock.shop_zoho_events;
|
||||
DROP TABLE mock.raw_shop_events;
|
||||
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,464 @@
|
||||
BEGIN;
|
||||
|
||||
|
||||
-- raw shop events
|
||||
|
||||
CREATE TABLE mock.raw_shop_events (
|
||||
platform TEXT NOT NULL,
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
raw_payload JSONB NOT NULL,
|
||||
|
||||
PRIMARY KEY (platform, shop_id, event_id, event_timestamp)
|
||||
);
|
||||
|
||||
|
||||
-- processed event tables
|
||||
|
||||
CREATE TABLE mock.shop_amazon_events (
|
||||
platform TEXT NOT NULL DEFAULT 'amazon' CHECK (platform = 'amazon'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_big_cartel_events (
|
||||
platform TEXT NOT NULL DEFAULT 'big_cartel' CHECK (platform = 'big_cartel'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_ebay_events (
|
||||
platform TEXT NOT NULL DEFAULT 'ebay' CHECK (platform = 'ebay'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_ecwid_events (
|
||||
platform TEXT NOT NULL DEFAULT 'ecwid' CHECK (platform = 'ecwid'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_etsy_events (
|
||||
platform TEXT NOT NULL DEFAULT 'etsy' CHECK (platform = 'etsy'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_shopify_events (
|
||||
platform TEXT NOT NULL DEFAULT 'shopify' CHECK (platform = 'shopify'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_square_online_events (
|
||||
platform TEXT NOT NULL DEFAULT 'square_online' CHECK (platform = 'square_online'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_squarespace_events (
|
||||
platform TEXT NOT NULL DEFAULT 'squarespace' CHECK (platform = 'squarespace'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_tiktok_events (
|
||||
platform TEXT NOT NULL DEFAULT 'tiktok' CHECK (platform = 'tiktok'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_walmart_marketplace_events (
|
||||
platform TEXT NOT NULL DEFAULT 'walmart_marketplace' CHECK (platform = 'walmart_marketplace'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_wix_events (
|
||||
platform TEXT NOT NULL DEFAULT 'wix' CHECK (platform = 'wix'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_woo_commerce_events (
|
||||
platform TEXT NOT NULL DEFAULT 'woo_commerce' CHECK (platform = 'woo_commerce'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
CREATE TABLE mock.shop_zoho_events (
|
||||
platform TEXT NOT NULL DEFAULT 'zoho' CHECK (platform = 'zoho'),
|
||||
shop_id TEXT NOT NULL,
|
||||
event_timestamp TIMESTAMPTZ NOT NULL,
|
||||
event_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (shop_id, event_id, event_timestamp),
|
||||
FOREIGN KEY (platform, shop_id, event_id, event_timestamp) REFERENCES mock.raw_shop_events
|
||||
);
|
||||
|
||||
|
||||
--- event processing
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_amazon_event() RETURNS TRIGGER AS $process_raw_amazon_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_amazon_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_amazon_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER amazon_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'amazon')
|
||||
EXECUTE FUNCTION mock.process_raw_amazon_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_big_cartel_event() RETURNS TRIGGER AS $process_raw_big_cartel_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_big_cartel_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_big_cartel_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER big_cartel_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'big_cartel')
|
||||
EXECUTE FUNCTION mock.process_raw_big_cartel_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_ebay_event() RETURNS TRIGGER AS $process_raw_ebay_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_ebay_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_ebay_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER ebay_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'ebay')
|
||||
EXECUTE FUNCTION mock.process_raw_ebay_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_ecwid_event() RETURNS TRIGGER AS $process_raw_ecwid_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_ecwid_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_ecwid_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER ecwid_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'ecwid')
|
||||
EXECUTE FUNCTION mock.process_raw_ecwid_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_etsy_event() RETURNS TRIGGER AS $process_raw_etsy_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_etsy_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_etsy_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER etsy_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'etsy')
|
||||
EXECUTE FUNCTION mock.process_raw_etsy_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_shopify_event() RETURNS TRIGGER AS $process_raw_shopify_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_shopify_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_shopify_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER shopify_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'shopify')
|
||||
EXECUTE FUNCTION mock.process_raw_shopify_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_square_online_event() RETURNS TRIGGER AS $process_raw_square_online_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_square_online_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_square_online_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER square_online_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'square_online')
|
||||
EXECUTE FUNCTION mock.process_raw_square_online_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_squarespace_event() RETURNS TRIGGER AS $process_raw_squarespace_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_squarespace_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_squarespace_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER squarespace_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'squarespace')
|
||||
EXECUTE FUNCTION mock.process_raw_squarespace_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_tiktok_event() RETURNS TRIGGER AS $process_raw_tiktok_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_tiktok_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_tiktok_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER tiktok_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'tiktok')
|
||||
EXECUTE FUNCTION mock.process_raw_tiktok_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_walmart_marketplace_event() RETURNS TRIGGER AS $process_raw_walmart_marketplace_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_walmart_marketplace_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_walmart_marketplace_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER walmart_marketplace_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'walmart_marketplace')
|
||||
EXECUTE FUNCTION mock.process_raw_walmart_marketplace_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_wix_event() RETURNS TRIGGER AS $process_raw_wix_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_wix_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_wix_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER wix_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'wix')
|
||||
EXECUTE FUNCTION mock.process_raw_wix_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_woo_commerce_event() RETURNS TRIGGER AS $process_raw_woo_commerce_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_woo_commerce_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_woo_commerce_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER woo_commerce_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'woo_commerce')
|
||||
EXECUTE FUNCTION mock.process_raw_woo_commerce_event();
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION mock.process_raw_zoho_event() RETURNS TRIGGER AS $process_raw_zoho_event$
|
||||
BEGIN
|
||||
INSERT INTO mock.shop_zoho_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id
|
||||
)
|
||||
SELECT
|
||||
NEW.platform,
|
||||
NEW.shop_id,
|
||||
NEW.event_timestamp,
|
||||
NEW.event_id;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$process_raw_zoho_event$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER zoho_store_events
|
||||
AFTER INSERT ON mock.raw_shop_events
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.platform = 'zoho')
|
||||
EXECUTE FUNCTION mock.process_raw_zoho_event();
|
||||
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,9 @@
|
||||
BEGIN;
|
||||
|
||||
|
||||
DROP TABLE mock.sale_form_shop_selection;
|
||||
DROP TABLE mock.refund_form_shop_selection;
|
||||
DROP TABLE mock.count_form_shop_selection;
|
||||
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,23 @@
|
||||
BEGIN;
|
||||
|
||||
|
||||
CREATE TABLE mock.sale_form_shop_selection (
|
||||
account_id INTEGER PRIMARY KEY,
|
||||
platform PLATFORM NOT NULL,
|
||||
shop_id TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE mock.refund_form_shop_selection (
|
||||
account_id INTEGER PRIMARY KEY,
|
||||
platform PLATFORM NOT NULL,
|
||||
shop_id TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE mock.count_form_shop_selection (
|
||||
account_id INTEGER PRIMARY KEY,
|
||||
platform PLATFORM NOT NULL,
|
||||
shop_id TEXT NOT NULL
|
||||
);
|
||||
|
||||
|
||||
COMMIT;
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 414 KiB After Width: | Height: | Size: 471 KiB |
@@ -9,6 +9,16 @@ entity "**accounts**" {
|
||||
*""user_id"": //text [FK]//
|
||||
}
|
||||
|
||||
entity "**raw_shop_events**" {
|
||||
+ ""platform"": //text [PK]//
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""raw_payload"": //jsonb //
|
||||
*""parsed"": //boolean //
|
||||
}
|
||||
|
||||
entity "**shop_amazon**" {
|
||||
+ ""account_id"": //integer [PK][FK]//
|
||||
+ ""shop_id"": //text [PK]//
|
||||
@@ -17,6 +27,14 @@ entity "**shop_amazon**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_amazon_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_amazon_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -63,6 +81,14 @@ entity "**shop_big_cartel**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_big_cartel_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_big_cartel_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -109,6 +135,14 @@ entity "**shop_ebay**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_ebay_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_ebay_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -155,6 +189,14 @@ entity "**shop_ecwid**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_ecwid_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_ecwid_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -201,6 +243,14 @@ entity "**shop_etsy**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_etsy_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_etsy_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -247,6 +297,14 @@ entity "**shop_shopify**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_shopify_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_shopify_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -293,6 +351,14 @@ entity "**shop_square_online**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_square_online_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_square_online_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -339,6 +405,14 @@ entity "**shop_squarespace**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_squarespace_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_squarespace_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -385,6 +459,14 @@ entity "**shop_tiktok**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_tiktok_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_tiktok_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -431,6 +513,14 @@ entity "**shop_walmart_marketplace**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_walmart_marketplace_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_walmart_marketplace_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -477,6 +567,14 @@ entity "**shop_wix**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_wix_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_wix_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -523,6 +621,14 @@ entity "**shop_woo_commerce**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_woo_commerce_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_woo_commerce_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -569,6 +675,14 @@ entity "**shop_zoho**" {
|
||||
*""name"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_zoho_events**" {
|
||||
+ ""store_id"": //text [PK]//
|
||||
+ ""event_timestamp"": //timestamp with time zone [PK][FK]//
|
||||
+ ""event_id"": //text [PK]//
|
||||
--
|
||||
*""platform"": //text //
|
||||
}
|
||||
|
||||
entity "**shop_zoho_listings**" {
|
||||
+ ""shop_id"": //text [PK][FK]//
|
||||
+ ""listing_id"": //text [PK]//
|
||||
@@ -654,6 +768,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_amazon**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_amazon_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_amazon_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_amazon_listings**" ||-|| "**shop_amazon**"
|
||||
@@ -684,6 +800,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_big_cartel**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_big_cartel_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_big_cartel_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_big_cartel_listings**" ||-|| "**shop_big_cartel**"
|
||||
@@ -714,6 +832,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_ebay**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_ebay_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_ebay_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_ebay_listings**" ||-|| "**shop_ebay**"
|
||||
@@ -744,6 +864,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_ecwid**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_ecwid_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_ecwid_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_ecwid_listings**" ||-|| "**shop_ecwid**"
|
||||
@@ -774,6 +896,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_etsy**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_etsy_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_etsy_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_etsy_listings**" ||-|| "**shop_etsy**"
|
||||
@@ -804,6 +928,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_shopify**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_shopify_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_shopify_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_shopify_listings**" ||-|| "**shop_shopify**"
|
||||
@@ -834,6 +960,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_square_online**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_square_online_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_square_online_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_square_online_listings**" ||-|| "**shop_square_online**"
|
||||
@@ -864,6 +992,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_squarespace**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_squarespace_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_squarespace_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_squarespace_listings**" ||-|| "**shop_squarespace**"
|
||||
@@ -894,6 +1024,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_tiktok**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_tiktok_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_tiktok_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_tiktok_listings**" ||-|| "**shop_tiktok**"
|
||||
@@ -924,6 +1056,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_walmart_marketplace**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_walmart_marketplace_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_walmart_marketplace_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_walmart_marketplace_listings**" ||-|| "**shop_walmart_marketplace**"
|
||||
@@ -954,6 +1088,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_wix**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_wix_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_wix_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_wix_listings**" ||-|| "**shop_wix**"
|
||||
@@ -984,6 +1120,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_woo_commerce**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_woo_commerce_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_woo_commerce_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_woo_commerce_listings**" ||-|| "**shop_woo_commerce**"
|
||||
@@ -1014,6 +1152,8 @@ entity "**sync_groups**" {
|
||||
|
||||
"**shop_zoho**" }-- "**public.oauth_users**"
|
||||
|
||||
"**shop_zoho_events**" ||-|| "**raw_shop_events**"
|
||||
|
||||
"**shop_zoho_listings**" }-- "**accounts**"
|
||||
|
||||
"**shop_zoho_listings**" ||-|| "**shop_zoho**"
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 61 KiB |
@@ -51,6 +51,12 @@ entity "**etsy_users**" {
|
||||
*""shop_id"": //integer //
|
||||
}
|
||||
|
||||
entity "**mock_mode**" {
|
||||
+ ""account_id"": //integer [PK][FK]//
|
||||
--
|
||||
*""mock_mode"": //boolean //
|
||||
}
|
||||
|
||||
entity "**oauth_login_states**" {
|
||||
+ ""state"": //bytea [PK]//
|
||||
--
|
||||
@@ -149,6 +155,8 @@ entity "**wix_store_events**" {
|
||||
|
||||
"**etsy_users**" }-- "**accounts**"
|
||||
|
||||
"**mock_mode**" ||-|| "**accounts**"
|
||||
|
||||
"**oauth_tokens**" }-- "**oauth_users**"
|
||||
|
||||
"**sync_group_listing_drafts**" }-- "**accounts**"
|
||||
|
||||
@@ -5,11 +5,13 @@ package accounts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
@@ -1461,6 +1463,290 @@ func (db *Store) DeleteListingInListingInMockSyncGroupBeingEdited(ctx context.Co
|
||||
return nil
|
||||
}
|
||||
|
||||
// if err := s.accts.SetShopInMockSaleForm(c, acctID, platform, shopID); err != nil {
|
||||
|
||||
func (db *Store) SetShopInMockSaleForm(ctx context.Context, acctID int64, platform Platform, shopID string) error {
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.sale_form_shop_selection (
|
||||
account_id,
|
||||
platform,
|
||||
shop_id
|
||||
)
|
||||
VALUES (
|
||||
@account_id,
|
||||
@platform,
|
||||
@shop_id
|
||||
)
|
||||
ON CONFLICT (account_id) DO UPDATE
|
||||
SET platform = EXCLUDED.platform,
|
||||
shop_id = EXCLUDED.shop_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Store) SetShopInMockRefundForm(ctx context.Context, acctID int64, platform Platform, shopID string) error {
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.refund_form_shop_selection (
|
||||
account_id,
|
||||
platform,
|
||||
shop_id
|
||||
)
|
||||
VALUES (
|
||||
@account_id,
|
||||
@platform,
|
||||
@shop_id
|
||||
)
|
||||
ON CONFLICT (account_id) DO UPDATE
|
||||
SET platform = EXCLUDED.platform,
|
||||
shop_id = EXCLUDED.shop_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Store) SetShopInMockCountForm(ctx context.Context, acctID int64, platform Platform, shopID string) error {
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.count_form_shop_selection (
|
||||
account_id,
|
||||
platform,
|
||||
shop_id
|
||||
)
|
||||
VALUES (
|
||||
@account_id,
|
||||
@platform,
|
||||
@shop_id
|
||||
)
|
||||
ON CONFLICT (account_id) DO UPDATE
|
||||
SET platform = EXCLUDED.platform,
|
||||
shop_id = EXCLUDED.shop_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type MockEventFormValues struct {
|
||||
SaleShopID string
|
||||
SalePlatform Platform
|
||||
RefundShopID string
|
||||
RefundPlatform Platform
|
||||
CountShopID string
|
||||
CountPlatform Platform
|
||||
}
|
||||
|
||||
func (db *Store) GetMockEventFormValues(ctx context.Context, acctID int64) (*MockEventFormValues, error) {
|
||||
rows, err := db.db.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
sf.platform AS sale_platform,
|
||||
sf.shop_id AS sale_shop_id,
|
||||
rf.platform AS refund_platform,
|
||||
rf.shop_id AS refund_shop_id,
|
||||
cf.platform AS count_platform,
|
||||
cf.shop_id AS count_shop_id
|
||||
FROM
|
||||
mock.sale_form_shop_selection AS sf
|
||||
FULL OUTER JOIN
|
||||
mock.refund_form_shop_selection AS rf
|
||||
USING
|
||||
(account_id)
|
||||
FULL OUTER JOIN
|
||||
mock.count_form_shop_selection AS cf
|
||||
USING
|
||||
(account_id)
|
||||
WHERE
|
||||
sf.account_id = @account_id
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"account_id": acctID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
v, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByNameLax[struct {
|
||||
Sale_shop_id pgtype.Text
|
||||
Sale_platform *Platform
|
||||
Refund_shop_id pgtype.Text
|
||||
Refund_platform *Platform
|
||||
Count_shop_id pgtype.Text
|
||||
Count_platform *Platform
|
||||
}])
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return &MockEventFormValues{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
return &MockEventFormValues{
|
||||
SaleShopID: v.Sale_shop_id.String,
|
||||
SalePlatform: deref(v.Sale_platform),
|
||||
RefundShopID: v.Refund_shop_id.String,
|
||||
RefundPlatform: deref(v.Refund_platform),
|
||||
CountShopID: v.Count_shop_id.String,
|
||||
CountPlatform: deref(v.Count_platform),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (db *Store) SaveNewMockSale(ctx context.Context, acctID int64, platform Platform, shopID, listingID string, count int) (uuid.UUID, error) {
|
||||
eventID := uuid.New()
|
||||
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.raw_shop_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id,
|
||||
raw_payload
|
||||
)
|
||||
VALUES (
|
||||
@platform,
|
||||
@shop_id,
|
||||
NOW(),
|
||||
@event_id,
|
||||
@raw_payload
|
||||
)
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
"event_id": eventID,
|
||||
"raw_payload": json.RawMessage(fmt.Sprintf(`{
|
||||
"type": "sale",
|
||||
"listingID": %q,
|
||||
"count": %d
|
||||
}`, listingID, count)),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return uuid.Nil, fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return eventID, nil
|
||||
}
|
||||
|
||||
func (db *Store) SaveNewMockRefund(ctx context.Context, acctID int64, platform Platform, shopID, listingID string, count int) (uuid.UUID, error) {
|
||||
eventID := uuid.New()
|
||||
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.raw_shop_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id,
|
||||
raw_payload
|
||||
)
|
||||
VALUES (
|
||||
@platform,
|
||||
@shop_id,
|
||||
NOW(),
|
||||
@event_id,
|
||||
@raw_payload
|
||||
)
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
"event_id": eventID,
|
||||
"raw_payload": json.RawMessage(fmt.Sprintf(`{
|
||||
"type": "refund",
|
||||
"listingID": %q,
|
||||
"count": %d
|
||||
}`, listingID, count)),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return uuid.Nil, fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return eventID, nil
|
||||
}
|
||||
|
||||
func (db *Store) SaveNewMockInventoryReset(ctx context.Context, acctID int64, platform Platform, shopID, listingID string, count int) (uuid.UUID, error) {
|
||||
eventID := uuid.New()
|
||||
|
||||
_, err := db.db.Exec(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO
|
||||
mock.raw_shop_events (
|
||||
platform,
|
||||
shop_id,
|
||||
event_timestamp,
|
||||
event_id,
|
||||
raw_payload
|
||||
)
|
||||
VALUES (
|
||||
@platform,
|
||||
@shop_id,
|
||||
NOW(),
|
||||
@event_id,
|
||||
@raw_payload
|
||||
)
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
"event_id": eventID,
|
||||
"raw_payload": json.RawMessage(fmt.Sprintf(`{
|
||||
"type": "inventory-reset",
|
||||
"listingID": %q,
|
||||
"count": %d
|
||||
}`, listingID, count)),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return uuid.Nil, fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
return eventID, nil
|
||||
}
|
||||
|
||||
// additional context
|
||||
|
||||
func (db *Store) GetAccountPointerByUserID(ctx context.Context, userID string) (*Account, error) {
|
||||
@@ -1481,3 +1767,11 @@ func (db *Store) beginReadonlyTxn(ctx context.Context, cb func(pgx.Tx) error) er
|
||||
func (db *Store) beginTxn(ctx context.Context, cb func(pgx.Tx) error) error {
|
||||
return pgx.BeginFunc(ctx, db.db, cb)
|
||||
}
|
||||
|
||||
func deref[T any](ptr *T) T {
|
||||
if ptr != nil {
|
||||
return *ptr
|
||||
}
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
|
||||
@@ -105,6 +105,22 @@ func (v_ctx *StoreWithContext) DeleteListingInListingInMockSyncGroupBeingEdited(
|
||||
return v_ctx.Store.DeleteListingInListingInMockSyncGroupBeingEdited(v_ctx.ctx, acctID, orderIndex)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) SetShopInMockSaleForm(acctID int64, platform Platform, shopID string) error {
|
||||
return v_ctx.Store.SetShopInMockSaleForm(v_ctx.ctx, acctID, platform, shopID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) SetShopInMockRefundForm(acctID int64, platform Platform, shopID string) error {
|
||||
return v_ctx.Store.SetShopInMockRefundForm(v_ctx.ctx, acctID, platform, shopID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) SetShopInMockCountForm(acctID int64, platform Platform, shopID string) error {
|
||||
return v_ctx.Store.SetShopInMockCountForm(v_ctx.ctx, acctID, platform, shopID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetMockEventFormValues(acctID int64) (*MockEventFormValues, error) {
|
||||
return v_ctx.Store.GetMockEventFormValues(v_ctx.ctx, acctID)
|
||||
}
|
||||
|
||||
func (v_ctx *StoreWithContext) GetAccountPointerByUserID(userID string) (*Account, error) {
|
||||
return v_ctx.Store.GetAccountPointerByUserID(v_ctx.ctx, userID)
|
||||
}
|
||||
|
||||
@@ -1235,11 +1235,3 @@ func (db *Store) listMockSyncGroupListings(ctx context.Context, tx pgx.Tx, acctI
|
||||
|
||||
return listings, nil
|
||||
}
|
||||
|
||||
func deref[T any](ptr *T) T {
|
||||
if ptr == nil {
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
return *ptr
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package reports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
"ruben/inventory2/consts"
|
||||
"ruben/inventory2/domains/accounts"
|
||||
)
|
||||
|
||||
type (
|
||||
RawShopEvent struct {
|
||||
Platform accounts.Platform
|
||||
ShopID string
|
||||
EventTimestamp time.Time
|
||||
EventID string
|
||||
RawPayload json.RawMessage
|
||||
}
|
||||
)
|
||||
|
||||
func (db *Store) GetRawShopEvents(ctx context.Context, acctID int64, platform accounts.Platform, shopID string) ([]RawShopEvent, error) {
|
||||
if _, err := db.accts.GetMockShop(ctx, acctID, platform, shopID); err != nil {
|
||||
if errors.Is(err, consts.ErrNotFound) {
|
||||
return nil, fmt.Errorf("shop not found: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to look up shop: %w", err)
|
||||
}
|
||||
|
||||
rows, err := db.db.Query(
|
||||
ctx,
|
||||
`
|
||||
SELECT
|
||||
event_timestamp,
|
||||
event_id,
|
||||
raw_payload
|
||||
FROM
|
||||
mock.raw_shop_events
|
||||
WHERE
|
||||
platform = @platform
|
||||
AND shop_id = @shop_id
|
||||
ORDER BY
|
||||
event_timestamp DESC,
|
||||
event_id ASC
|
||||
`,
|
||||
pgx.NamedArgs{
|
||||
"platform": platform,
|
||||
"shop_id": shopID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to perform query: %w", err)
|
||||
}
|
||||
|
||||
vs, err := pgx.CollectRows(rows, pgx.RowToStructByNameLax[struct {
|
||||
Event_timestamp time.Time
|
||||
Event_id string
|
||||
Raw_payload json.RawMessage
|
||||
}])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan rows: %w", err)
|
||||
}
|
||||
|
||||
evts := make([]RawShopEvent, len(vs))
|
||||
for i, v := range vs {
|
||||
evts[i] = RawShopEvent{
|
||||
Platform: platform,
|
||||
ShopID: shopID,
|
||||
EventTimestamp: v.Event_timestamp,
|
||||
EventID: v.Event_id,
|
||||
RawPayload: v.Raw_payload,
|
||||
}
|
||||
}
|
||||
|
||||
return evts, nil
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package reports
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"ruben/inventory2/domains/accounts"
|
||||
"ruben/inventory2/logging"
|
||||
)
|
||||
|
||||
//go:generate concurry -s Store
|
||||
|
||||
type (
|
||||
Store struct {
|
||||
log *logging.Logger
|
||||
db *pgxpool.Pool
|
||||
accts *accounts.Store
|
||||
}
|
||||
)
|
||||
|
||||
func NewStore(logger *logging.Logger, db *pgxpool.Pool, accts *accounts.Store) *Store {
|
||||
return &Store{
|
||||
log: logger,
|
||||
db: db,
|
||||
accts: accts,
|
||||
}
|
||||
}
|
||||
|
||||
func (db *Store) WithContext(ctx context.Context) *StoreWithContext {
|
||||
return NewStoreWithContext(ctx, db)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Code generated by concurry DO NOT EDIT.
|
||||
// https://github.com/angelbeltran/concurry
|
||||
// concurry
|
||||
package reports
|
||||
|
||||
import (
|
||||
"context"
|
||||
"ruben/inventory2/domains/accounts"
|
||||
)
|
||||
|
||||
type StoreWithContext struct {
|
||||
ctx context.Context
|
||||
*Store
|
||||
}
|
||||
|
||||
func NewStoreWithContext(ctx context.Context, v *Store) *StoreWithContext {
|
||||
return &StoreWithContext{
|
||||
ctx: ctx,
|
||||
Store: v,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"ruben/inventory2/domains/authentication"
|
||||
etsy_platform "ruben/inventory2/domains/platforms/etsy"
|
||||
"ruben/inventory2/domains/raw_events"
|
||||
"ruben/inventory2/domains/reports"
|
||||
"ruben/inventory2/logging"
|
||||
"ruben/inventory2/server"
|
||||
)
|
||||
@@ -151,11 +152,14 @@ func runAuthProcesses(ctx context.Context, auth *authentication.Authenticator) <
|
||||
}
|
||||
|
||||
func runServer(ctx context.Context, logger *logging.Logger, connPool *pgxpool.Pool, auth *authentication.Authenticator) <-chan error {
|
||||
accts := accounts.NewStore(logger, connPool)
|
||||
|
||||
r := server.NewRouter(
|
||||
logger.WithGroup("server"),
|
||||
"./",
|
||||
raw_events.NewStore(logger.WithGroup("raw-event-store"), connPool),
|
||||
accounts.NewStore(logger, connPool),
|
||||
accts,
|
||||
reports.NewStore(logger, connPool, accts),
|
||||
etsy_platform.NewPlatform(
|
||||
logger,
|
||||
func(acctID int64) string {
|
||||
|
||||
@@ -78,6 +78,14 @@ func Routes(
|
||||
mockSyncGroupBeingEdited.PUT("/listings/:orderIndex/shop", response.Handler(as.setShopInListingInMockSyncGroupBeingEdited))
|
||||
mockSyncGroupBeingEdited.PUT("/listings/:orderIndex/listing", response.Handler(as.setListingInListingInMockSyncGroupBeingEdited))
|
||||
mockSyncGroupBeingEdited.DELETE("/listings/:orderIndex", response.Handler(as.deleteListingInListingInMockSyncGroupBeingEdited))
|
||||
|
||||
simulations := r.Group("/:acctID/simulations", pub.Publish("/:acctID/simulations"))
|
||||
simulations.PUT("/sale/form/shop", response.Handler(as.setShopInMockSaleForm))
|
||||
simulations.POST("/sale", response.Handler(as.postNewMockSale))
|
||||
simulations.PUT("/refund/form/shop", response.Handler(as.setShopInMockRefundForm))
|
||||
simulations.POST("/refund", response.Handler(as.postNewMockRefund))
|
||||
simulations.PUT("/count/form/shop", response.Handler(as.setShopInMockCountForm))
|
||||
simulations.PUT("/shops/:shopID/listings/:listingID/count", response.Handler(as.setMockListingCount))
|
||||
}
|
||||
|
||||
// POST /
|
||||
@@ -736,6 +744,150 @@ func (s *accountSubrouter) deleteListingInListingInMockSyncGroupBeingEdited(c *g
|
||||
return response.StatusOK(), nil
|
||||
}
|
||||
|
||||
// PUT /:acctID/simulations/sale/form/shop
|
||||
func (s *accountSubrouter) setShopInMockSaleForm(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Form("shop-id", param.Text(&shopID)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.accts.SetShopInMockSaleForm(c, acctID, platform, shopID); err != nil {
|
||||
return nil, fmt.Errorf("failed to set shop in mock sale form: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusOK(), nil
|
||||
}
|
||||
|
||||
// POST /:acctID/simulations/sale
|
||||
func (s *accountSubrouter) postNewMockSale(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
listingID string
|
||||
count int
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Form("shop-id", param.Text(&shopID)).
|
||||
Form("listing-id", param.Text(&listingID)).
|
||||
Form("count", param.Int(&count)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := s.accts.SaveNewMockSale(c, acctID, platform, shopID, listingID, count); err != nil {
|
||||
return nil, fmt.Errorf("failed to save new mock sale: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusCreated(), nil
|
||||
}
|
||||
|
||||
// PUT /:acctID/simulations/refund/form/shop
|
||||
func (s *accountSubrouter) setShopInMockRefundForm(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Form("shop-id", param.Text(&shopID)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.accts.SetShopInMockRefundForm(c, acctID, platform, shopID); err != nil {
|
||||
return nil, fmt.Errorf("failed to set shop in mock refund form: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusOK(), nil
|
||||
}
|
||||
|
||||
// POST /:acctID/simulations/refund
|
||||
func (s *accountSubrouter) postNewMockRefund(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
listingID string
|
||||
count int
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Form("shop-id", param.Text(&shopID)).
|
||||
Form("listing-id", param.Text(&listingID)).
|
||||
Form("count", param.Int(&count)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := s.accts.SaveNewMockRefund(c, acctID, platform, shopID, listingID, count); err != nil {
|
||||
return nil, fmt.Errorf("failed to save new mock refund: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusCreated(), nil
|
||||
}
|
||||
|
||||
// PUT /:acctID/simulations/count/form/shop
|
||||
func (s *accountSubrouter) setShopInMockCountForm(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Form("shop-id", param.Text(&shopID)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.accts.SetShopInMockCountForm(c, acctID, platform, shopID); err != nil {
|
||||
return nil, fmt.Errorf("failed to set shop in mock count form: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusOK(), nil
|
||||
}
|
||||
|
||||
// PUT /:acctID/simulations/shops/:shopID/listings/:listingID/count
|
||||
func (s *accountSubrouter) setMockListingCount(c *gin.Context) (response.Response, error) {
|
||||
acctID := auth.GetIdentity(c).Account.AccountID
|
||||
|
||||
var (
|
||||
platform accounts.Platform
|
||||
shopID string
|
||||
listingID string
|
||||
count int
|
||||
)
|
||||
|
||||
if err := param.Form("platform", param.Platform(&platform)).
|
||||
Path("shopID", param.Text(&shopID)).
|
||||
Path("listingID", param.Text(&listingID)).
|
||||
Form("count", param.Int(&count)).
|
||||
Unmarshal(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := s.accts.SaveNewMockInventoryReset(c, acctID, platform, shopID, listingID, count); err != nil {
|
||||
return nil, fmt.Errorf("failed to save new mock inventory reset: %w", err)
|
||||
}
|
||||
|
||||
return response.StatusOK(), nil
|
||||
}
|
||||
|
||||
func lowerSnakeCase(s accounts.Platform) string {
|
||||
return strings.ToLower(strings.Join(strings.Split(string(s), " "), "_"))
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"ruben/inventory2/domains/authentication"
|
||||
etsy_platform "ruben/inventory2/domains/platforms/etsy"
|
||||
"ruben/inventory2/domains/raw_events"
|
||||
"ruben/inventory2/domains/reports"
|
||||
"ruben/inventory2/logging"
|
||||
"ruben/inventory2/server/api"
|
||||
"ruben/inventory2/server/auth"
|
||||
@@ -30,6 +31,7 @@ func NewRouter(
|
||||
contentDir string,
|
||||
rawEvents *raw_events.Store,
|
||||
accts *accounts.Store,
|
||||
reps *reports.Store,
|
||||
etsy *etsy_platform.Platform,
|
||||
authr *authentication.Authenticator,
|
||||
) *Router {
|
||||
@@ -59,6 +61,7 @@ func NewRouter(
|
||||
"/ui",
|
||||
rawEvents,
|
||||
accts,
|
||||
reps,
|
||||
etsy,
|
||||
authM.Authenticate(),
|
||||
)
|
||||
|
||||
+17
-1
@@ -16,6 +16,7 @@ import (
|
||||
"ruben/inventory2/domains/accounts"
|
||||
etsy_platform "ruben/inventory2/domains/platforms/etsy"
|
||||
"ruben/inventory2/domains/raw_events"
|
||||
"ruben/inventory2/domains/reports"
|
||||
"ruben/inventory2/logging"
|
||||
"ruben/inventory2/server/auth"
|
||||
"ruben/inventory2/server/response"
|
||||
@@ -28,6 +29,7 @@ type (
|
||||
templater *templater.Templater
|
||||
rawEvents *raw_events.Store
|
||||
accts *accounts.Store
|
||||
reports *reports.Store
|
||||
etsy *etsy_platform.Platform
|
||||
}
|
||||
|
||||
@@ -44,6 +46,7 @@ func Routes(
|
||||
uiPath string,
|
||||
rawEvents *raw_events.Store,
|
||||
accts *accounts.Store,
|
||||
reps *reports.Store,
|
||||
etsy *etsy_platform.Platform,
|
||||
authenticate gin.HandlerFunc,
|
||||
) {
|
||||
@@ -143,6 +146,7 @@ func Routes(
|
||||
}),
|
||||
rawEvents: rawEvents,
|
||||
accts: accts,
|
||||
reports: reps,
|
||||
etsy: etsy,
|
||||
}
|
||||
|
||||
@@ -170,6 +174,14 @@ func (s *webpageRouter) serveTemplate(c *gin.Context) (response.Response, error)
|
||||
|
||||
r := c.Request
|
||||
ctx := r.Context()
|
||||
id := auth.GetIdentity(ctx)
|
||||
var mockMode bool
|
||||
if id.Account != nil {
|
||||
var err error
|
||||
if mockMode, err = s.accts.GetMockMode(ctx, id.Account.AccountID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
args := []any{
|
||||
"Request",
|
||||
@@ -181,12 +193,16 @@ func (s *webpageRouter) serveTemplate(c *gin.Context) (response.Response, error)
|
||||
newURLCalculator(r.URL),
|
||||
"Accounts",
|
||||
s.accts.WithContext(ctx),
|
||||
"Reports",
|
||||
s.reports.WithContext(ctx),
|
||||
"Etsy",
|
||||
s.etsy.WithContext(ctx),
|
||||
"MockMode",
|
||||
mockMode,
|
||||
|
||||
// auth tooling
|
||||
"Identity",
|
||||
auth.GetIdentity(ctx),
|
||||
id,
|
||||
"Auth",
|
||||
newTemplateAuthenticator(r),
|
||||
}
|
||||
|
||||
+52
-74
@@ -197,29 +197,6 @@
|
||||
.bottom-0 {
|
||||
bottom: calc(var(--spacing) * 0);
|
||||
}
|
||||
.grid-table-\[1fr_1fr_1fr_1fr_1fr_1fr\] {
|
||||
&:is(table) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||
& > :is(thead, tbody, tfoot) {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: -1;
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
& > tr {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: -1;
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
& > th, & > td {
|
||||
grid-column: span 1;
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-table-\[1fr_1fr_1fr_1fr_1fr_1fr_1fr\] {
|
||||
&:is(table) {
|
||||
display: grid;
|
||||
@@ -273,6 +250,9 @@
|
||||
max-width: 96rem;
|
||||
}
|
||||
}
|
||||
.m-0 {
|
||||
margin: calc(var(--spacing) * 0);
|
||||
}
|
||||
.m-\[0\.5em\] {
|
||||
margin: 0.5em;
|
||||
}
|
||||
@@ -294,6 +274,9 @@
|
||||
.my-\[0\.5em\] {
|
||||
margin-block: 0.5em;
|
||||
}
|
||||
.my-\[1em\] {
|
||||
margin-block: 1em;
|
||||
}
|
||||
.my-\[1rem\] {
|
||||
margin-block: 1rem;
|
||||
}
|
||||
@@ -390,9 +373,6 @@
|
||||
.flex-shrink {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.flex-grow-\[1\] {
|
||||
flex-grow: 1;
|
||||
}
|
||||
@@ -408,12 +388,6 @@
|
||||
.basis-full {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
.border-collapse {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.transform {
|
||||
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
||||
}
|
||||
.animate-pulse {
|
||||
animation: var(--animate-pulse);
|
||||
}
|
||||
@@ -462,6 +436,9 @@
|
||||
.gap-\[0\.25em\] {
|
||||
gap: 0.25em;
|
||||
}
|
||||
.gap-\[0\.75em\] {
|
||||
gap: 0.75em;
|
||||
}
|
||||
.gap-\[1em\] {
|
||||
gap: 1em;
|
||||
}
|
||||
@@ -506,6 +483,10 @@
|
||||
border-style: var(--tw-border-style);
|
||||
border-width: 1px;
|
||||
}
|
||||
.border-\[2px\] {
|
||||
border-style: var(--tw-border-style);
|
||||
border-width: 2px;
|
||||
}
|
||||
.border-b-\[2px\] {
|
||||
border-bottom-style: var(--tw-border-style);
|
||||
border-bottom-width: 2px;
|
||||
@@ -514,6 +495,12 @@
|
||||
--tw-border-style: solid;
|
||||
border-style: solid;
|
||||
}
|
||||
.border-\[gray\] {
|
||||
border-color: gray;
|
||||
}
|
||||
.border-border {
|
||||
border-color: var(--border);
|
||||
}
|
||||
.border-foreground {
|
||||
border-color: var(--foreground);
|
||||
}
|
||||
@@ -553,6 +540,9 @@
|
||||
.py-\[1em\] {
|
||||
padding-block: 1em;
|
||||
}
|
||||
.py-\[2em\] {
|
||||
padding-block: 2em;
|
||||
}
|
||||
.pt-\[1em\] {
|
||||
padding-top: 1em;
|
||||
}
|
||||
@@ -574,9 +564,6 @@
|
||||
.font-display {
|
||||
font-family: var(--display-family);
|
||||
}
|
||||
.font-text {
|
||||
font-family: var(--text-family);
|
||||
}
|
||||
.text-lg {
|
||||
font-size: var(--text-lg);
|
||||
line-height: var(--tw-leading, var(--text-lg--line-height));
|
||||
@@ -592,10 +579,6 @@
|
||||
.text-\[1\.5em\] {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.font-\[1\.5em\] {
|
||||
--tw-font-weight: 1.5em;
|
||||
font-weight: 1.5em;
|
||||
}
|
||||
.font-bold {
|
||||
--tw-font-weight: var(--font-weight-bold);
|
||||
font-weight: var(--font-weight-bold);
|
||||
@@ -607,12 +590,6 @@
|
||||
.text-nowrap {
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
.text-wrap {
|
||||
text-wrap: wrap;
|
||||
}
|
||||
.text-inherit {
|
||||
color: inherit;
|
||||
}
|
||||
.capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
@@ -622,10 +599,6 @@
|
||||
.underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
.outline {
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 1px;
|
||||
}
|
||||
.outline-1 {
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 1px;
|
||||
@@ -852,6 +825,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.active\:bg-accent-secondary {
|
||||
&:active {
|
||||
background-color: var(--accent-secondary);
|
||||
}
|
||||
}
|
||||
.disabled\:cursor-not-allowed {
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
@@ -1200,26 +1178,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@property --tw-rotate-x {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-rotate-y {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-rotate-z {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-skew-x {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-skew-y {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-border-style {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
@@ -1302,6 +1260,26 @@
|
||||
inherits: false;
|
||||
initial-value: 1;
|
||||
}
|
||||
@property --tw-rotate-x {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-rotate-y {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-rotate-z {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-skew-x {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-skew-y {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-content {
|
||||
syntax: "*";
|
||||
initial-value: "";
|
||||
@@ -1319,11 +1297,6 @@
|
||||
@layer properties {
|
||||
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
||||
*, ::before, ::after, ::backdrop {
|
||||
--tw-rotate-x: initial;
|
||||
--tw-rotate-y: initial;
|
||||
--tw-rotate-z: initial;
|
||||
--tw-skew-x: initial;
|
||||
--tw-skew-y: initial;
|
||||
--tw-border-style: solid;
|
||||
--tw-font-weight: initial;
|
||||
--tw-outline-style: solid;
|
||||
@@ -1343,6 +1316,11 @@
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-scale-z: 1;
|
||||
--tw-rotate-x: initial;
|
||||
--tw-rotate-y: initial;
|
||||
--tw-rotate-z: initial;
|
||||
--tw-skew-x: initial;
|
||||
--tw-skew-y: initial;
|
||||
--tw-content: "";
|
||||
--tw-leading: initial;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,27 @@
|
||||
hx-trigger="sse:accounts_{{$acctID}}_mock-mode"
|
||||
hx-swap="morph"
|
||||
>
|
||||
{{- $mockMode := .Accounts.GetMockMode $acctID }}
|
||||
{{- $mockMode := .MockMode }}
|
||||
|
||||
<form id="mock-mode-form">
|
||||
<label class="flex items-center gap-[0.5em] font-display text-[1.5em]">
|
||||
<label
|
||||
class="
|
||||
flex
|
||||
items-center
|
||||
gap-[0.5em]
|
||||
font-display
|
||||
text-[1.5em]
|
||||
cursor-pointer
|
||||
w-fit
|
||||
"
|
||||
>
|
||||
Mock Mode
|
||||
<input
|
||||
type="checkbox"
|
||||
{{- if $mockMode }}
|
||||
checked
|
||||
{{- end }}
|
||||
class="h-[1em] w-[1em]"
|
||||
class="h-[1em] w-[1em] cursor-pointer"
|
||||
hx-put="/api/accounts/{{$acctID}}/mock-mode"
|
||||
hx-vals='{"on": {{not $mockMode}}}'
|
||||
hx-swap="none"
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
{{/* [ .Shops, .SelectedPlatform, .SelectedShopID, .Listings ] */}}
|
||||
|
||||
{{- $acctID := .Identity.Account.AccountID -}}
|
||||
{{- $shops := .Shops }}
|
||||
{{- if not $shops }}
|
||||
{{- $shops = .Accounts.GetMockShops $acctID -}}
|
||||
{{- end }}
|
||||
{{- $selectedPlatform := .SelectedPlatform }}
|
||||
{{- $selectedShopID := .SelectedShopID }}
|
||||
{{- if not $selectedPlatform | or (not $selectedShopID) }}
|
||||
{{- $formSelections := .Accounts.GetMockEventFormValues $acctID }}
|
||||
{{- $selectedPlatform = $formSelections.RefundPlatform }}
|
||||
{{- $selectedShopID = $formSelections.RefundShopID }}
|
||||
{{- end }}
|
||||
{{- $listings := .Listings }}
|
||||
{{- if $selectedShopID }}
|
||||
{{ $listings = .Accounts.GetMockListingsForShop $acctID $selectedPlatform $selectedShopID }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
||||
{{/* REFUNDS */}}
|
||||
{{- define "refund-accordion-header" }}
|
||||
<h2 class="inline-block">
|
||||
Refund
|
||||
</h2>
|
||||
{{ end }}
|
||||
|
||||
{{- define "refund-accordion-body" }}
|
||||
{{ $acctID := .Identity.Account.AccountID }}
|
||||
{{ $selectedPlatform := .SelectedPlatform }}
|
||||
{{ $selectedShopID := .SelectedShopID }}
|
||||
{{ $listings := .Listings }}
|
||||
|
||||
{{/* form updater*/}}
|
||||
<div
|
||||
hidden
|
||||
hx-trigger="sse:accounts_{{$acctID}}_simulations_refund"
|
||||
hx-get="/ui/accounts/{{$acctID}}/simulations/refund-form"
|
||||
hx-select="#refund-form"
|
||||
hx-target="#refund-form"
|
||||
>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="refund-form"
|
||||
class="flex flex-col items-center gap-[0.75em]"
|
||||
hx-post="/api/accounts/{{$acctID}}/simulations/refund"
|
||||
hx-swap="none"
|
||||
hx-vals='js:{
|
||||
"platform": {{printf "%q" $selectedPlatform}},
|
||||
"shop-id": {{printf "%q" $selectedShopID}},
|
||||
}'
|
||||
>
|
||||
<select
|
||||
name="shop-id"
|
||||
class="bg-background"
|
||||
required
|
||||
hx-put="/api/accounts/{{$acctID}}/simulations/refund/form/shop"
|
||||
hx-vals='js:{
|
||||
platform: event.target.value.replace(/-[^ ]*/, ""),
|
||||
"shop-id": event.target.value.replace(/[^ -]*-/, "")
|
||||
}'
|
||||
>
|
||||
<option disabled selected>
|
||||
- Select A Shop -
|
||||
</option>
|
||||
{{- range $shop := .Shops }}
|
||||
<option
|
||||
value="{{$shop.Platform}}-{{$shop.ShopID}}"
|
||||
{{- if and
|
||||
(eq $shop.Platform $selectedPlatform)
|
||||
(eq $shop.ShopID $selectedShopID)
|
||||
}}
|
||||
selected
|
||||
{{- end }}
|
||||
>
|
||||
{{ $shop.Name }}
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<select
|
||||
name="listing-id"
|
||||
class="bg-background"
|
||||
required
|
||||
>
|
||||
{{- if $listings }}
|
||||
<option disabled selected>
|
||||
- Select A Listing -
|
||||
</option>
|
||||
{{- range $listing := $listings }}
|
||||
<option value="{{$listing.ListingID}}">
|
||||
{{ $listing.Name }} - {{ $listing.SKU }}
|
||||
</option>
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
<option disabled selected>
|
||||
- No Listings Found -
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<input
|
||||
class="p-[0.5em] border-medium border-border rounded-lg bg-background"
|
||||
type="number"
|
||||
min="1"
|
||||
max="1000000000"
|
||||
name="count"
|
||||
value="0"
|
||||
required
|
||||
/>
|
||||
|
||||
<div>
|
||||
{{ component "button"
|
||||
"Text" "Submit"
|
||||
"Background" true
|
||||
"Class" "m-0"
|
||||
}}
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
{{ component "accordion"
|
||||
"Name" "simulate"
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $selectedPlatform
|
||||
"SelectedShopID" $selectedShopID
|
||||
"Listings" $listings
|
||||
"Class" `
|
||||
mx-[1em]
|
||||
mb-[1em]
|
||||
`
|
||||
"#accordion-header" "refund-accordion-header"
|
||||
"#accordion-body" "refund-accordion-body"
|
||||
}}
|
||||
@@ -0,0 +1,136 @@
|
||||
{{/* [ .Shops, .SelectedPlatform, .SelectedShopID, .Listings ] */}}
|
||||
|
||||
{{- $acctID := .Identity.Account.AccountID -}}
|
||||
{{- $shops := .Shops }}
|
||||
{{- if not $shops }}
|
||||
{{- $shops = .Accounts.GetMockShops $acctID -}}
|
||||
{{- end }}
|
||||
{{- $selectedPlatform := .SelectedPlatform }}
|
||||
{{- $selectedShopID := .SelectedShopID }}
|
||||
{{- if not $selectedPlatform | or (not $selectedShopID) }}
|
||||
{{- $formSelections := .Accounts.GetMockEventFormValues $acctID }}
|
||||
{{- $selectedPlatform = $formSelections.SalePlatform }}
|
||||
{{- $selectedShopID = $formSelections.SaleShopID }}
|
||||
{{- end }}
|
||||
{{- $listings := .Listings }}
|
||||
{{- if $selectedShopID }}
|
||||
{{ $listings = .Accounts.GetMockListingsForShop $acctID $selectedPlatform $selectedShopID }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
||||
{{/* SALES */}}
|
||||
{{- define "sale-accordion-header" }}
|
||||
<h2 class="inline-block">
|
||||
Sale
|
||||
</h2>
|
||||
{{ end }}
|
||||
|
||||
{{- define "sale-accordion-body" }}
|
||||
{{ $acctID := .Identity.Account.AccountID }}
|
||||
{{ $selectedPlatform := .SelectedPlatform }}
|
||||
{{ $selectedShopID := .SelectedShopID }}
|
||||
{{ $listings := .Listings }}
|
||||
|
||||
{{/* form updater*/}}
|
||||
<div
|
||||
hidden
|
||||
hx-trigger="sse:accounts_{{$acctID}}_simulations_sale"
|
||||
hx-get="/ui/accounts/{{$acctID}}/simulations/sales-form"
|
||||
hx-select="#sales-form"
|
||||
hx-target="#sales-form"
|
||||
>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="sales-form"
|
||||
class="flex flex-col items-center gap-[0.75em]"
|
||||
hx-post="/api/accounts/{{$acctID}}/simulations/sale"
|
||||
hx-swap="none"
|
||||
hx-vals='js:{
|
||||
"platform": {{printf "%q" $selectedPlatform}},
|
||||
"shop-id": {{printf "%q" $selectedShopID}},
|
||||
}'
|
||||
>
|
||||
<select
|
||||
name="shop-id"
|
||||
class="bg-background"
|
||||
required
|
||||
hx-put="/api/accounts/{{$acctID}}/simulations/sale/form/shop"
|
||||
hx-vals='js:{
|
||||
platform: event.target.value.replace(/-[^ ]*/, ""),
|
||||
"shop-id": event.target.value.replace(/[^ -]*-/, "")
|
||||
}'
|
||||
>
|
||||
<option disabled selected>
|
||||
- Select A Shop -
|
||||
</option>
|
||||
{{- range $shop := .Shops }}
|
||||
<option
|
||||
value="{{$shop.Platform}}-{{$shop.ShopID}}"
|
||||
{{- if and
|
||||
(eq $shop.Platform $selectedPlatform)
|
||||
(eq $shop.ShopID $selectedShopID)
|
||||
}}
|
||||
selected
|
||||
{{- end }}
|
||||
>
|
||||
{{ $shop.Name }}
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<select
|
||||
name="listing-id"
|
||||
class="bg-background"
|
||||
required
|
||||
>
|
||||
{{- if $listings }}
|
||||
<option disabled selected>
|
||||
- Select A Listing -
|
||||
</option>
|
||||
{{- range $listing := $listings }}
|
||||
<option value="{{$listing.ListingID}}">
|
||||
{{ $listing.Name }} - {{ $listing.SKU }}
|
||||
</option>
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
<option disabled selected>
|
||||
- No Listings Found -
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<input
|
||||
class="p-[0.5em] border-medium border-border rounded-lg bg-background"
|
||||
type="number"
|
||||
min="1"
|
||||
max="1000000000"
|
||||
name="count"
|
||||
value="0"
|
||||
required
|
||||
/>
|
||||
|
||||
<div>
|
||||
{{ component "button"
|
||||
"Text" "Submit"
|
||||
"Background" true
|
||||
"Class" "m-0"
|
||||
}}
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
{{ component "accordion"
|
||||
"Name" "simulate"
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $selectedPlatform
|
||||
"SelectedShopID" $selectedShopID
|
||||
"Listings" $listings
|
||||
"Class" `
|
||||
mx-[1em]
|
||||
mb-[1em]
|
||||
`
|
||||
"#accordion-header" "sale-accordion-header"
|
||||
"#accordion-body" "sale-accordion-body"
|
||||
}}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
{{/* [ .Shops, .SelectedPlatform, .SelectedShopID, .Listings ] */}}
|
||||
|
||||
{{- $acctID := .Identity.Account.AccountID -}}
|
||||
{{- $shops := .Shops }}
|
||||
{{- if not $shops }}
|
||||
{{- $shops = .Accounts.GetMockShops $acctID -}}
|
||||
{{- end }}
|
||||
{{- $selectedPlatform := .SelectedPlatform }}
|
||||
{{- $selectedShopID := .SelectedShopID }}
|
||||
{{- if not $selectedPlatform | or (not $selectedShopID) }}
|
||||
{{- $formSelections := .Accounts.GetMockEventFormValues $acctID }}
|
||||
{{- $selectedPlatform = $formSelections.CountPlatform }}
|
||||
{{- $selectedShopID = $formSelections.CountShopID }}
|
||||
{{- end }}
|
||||
{{- $listings := .Listings }}
|
||||
{{- if $selectedShopID }}
|
||||
{{ $listings = .Accounts.GetMockListingsForShop $acctID $selectedPlatform $selectedShopID }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
||||
{{/* SET INVENTORY */}}
|
||||
{{- define "set-inventory-accordion-header" }}
|
||||
<h2 class="inline-block">
|
||||
Set Inventory
|
||||
</h2>
|
||||
{{ end }}
|
||||
|
||||
{{- define "set-inventory-accordion-body" }}
|
||||
{{ $acctID := .Identity.Account.AccountID }}
|
||||
{{ $selectedPlatform := .SelectedPlatform }}
|
||||
{{ $selectedShopID := .SelectedShopID }}
|
||||
{{ $listings := .Listings }}
|
||||
|
||||
{{/* form updater*/}}
|
||||
<div
|
||||
hidden
|
||||
hx-trigger="sse:accounts_{{$acctID}}_simulations_shops"
|
||||
hx-get="/ui/accounts/{{$acctID}}/simulations/set-inventory-form"
|
||||
hx-select="#set-inventory-form"
|
||||
hx-target="#set-inventory-form"
|
||||
>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="set-inventory-form"
|
||||
class="flex flex-col items-center gap-[0.75em]"
|
||||
hx-put="/api/accounts/{{$acctID}}/simulations/shops/{shop-id}/listings/{listing-id}/count"
|
||||
hx-swap="none"
|
||||
hx-vals='js:{
|
||||
"platform": {{printf "%q" $selectedPlatform}},
|
||||
"shop-id": {{printf "%q" $selectedShopID}},
|
||||
}'
|
||||
>
|
||||
<select
|
||||
name="shop-id"
|
||||
class="bg-background"
|
||||
required
|
||||
hx-put="/api/accounts/{{$acctID}}/simulations/count/form/shop"
|
||||
hx-vals='js:{
|
||||
platform: event.target.value.replace(/-[^ ]*/, ""),
|
||||
"shop-id": event.target.value.replace(/[^ -]*-/, "")
|
||||
}'
|
||||
>
|
||||
<option disabled selected>
|
||||
- Select A Shop -
|
||||
</option>
|
||||
{{- range $shop := .Shops }}
|
||||
<option
|
||||
value="{{$shop.Platform}}-{{$shop.ShopID}}"
|
||||
{{- if and
|
||||
(eq $shop.Platform $selectedPlatform)
|
||||
(eq $shop.ShopID $selectedShopID)
|
||||
}}
|
||||
selected
|
||||
{{- end }}
|
||||
>
|
||||
{{ $shop.Name }}
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<select
|
||||
name="listing-id"
|
||||
class="bg-background"
|
||||
required
|
||||
>
|
||||
{{- if $listings }}
|
||||
<option disabled selected>
|
||||
- Select A Listing -
|
||||
</option>
|
||||
{{- range $listing := $listings }}
|
||||
<option value="{{$listing.ListingID}}">
|
||||
{{ $listing.Name }} - {{ $listing.SKU }}
|
||||
</option>
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
<option disabled selected>
|
||||
- No Listings Found -
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<input
|
||||
class="p-[0.5em] border-medium border-border rounded-lg bg-background"
|
||||
type="number"
|
||||
min="1"
|
||||
max="1000000000"
|
||||
name="count"
|
||||
value="0"
|
||||
required
|
||||
/>
|
||||
|
||||
<div>
|
||||
{{ component "button"
|
||||
"Text" "Submit"
|
||||
"Background" true
|
||||
"Class" "m-0"
|
||||
}}
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
|
||||
{{ component "accordion"
|
||||
"Name" "simulate"
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $selectedPlatform
|
||||
"SelectedShopID" $selectedShopID
|
||||
"Listings" $listings
|
||||
"Class" `
|
||||
mx-[1em]
|
||||
mb-[1em]
|
||||
`
|
||||
"#accordion-header" "set-inventory-accordion-header"
|
||||
"#accordion-body" "set-inventory-accordion-body"
|
||||
}}
|
||||
@@ -4,13 +4,14 @@
|
||||
<button
|
||||
class="
|
||||
border-thin
|
||||
bg-card
|
||||
{{if .Background}}bg-background{{else}}bg-card{{end}}
|
||||
rounded-sm
|
||||
p-[0.5em]
|
||||
font-semibold
|
||||
cursor-pointer
|
||||
hover:underline
|
||||
hover:bg-accent
|
||||
active:bg-accent-secondary
|
||||
disabled:bg-accent-secondary
|
||||
disabled:cursor-not-allowed
|
||||
disabled:no-underline
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
{{- $loggedIn := and (and .Identity .Identity.AccessToken) true -}}
|
||||
{{- $hasAccount := and (and .Identity .Identity.Account) true -}}
|
||||
{{- $acctID := 0 }}
|
||||
{{- $mockMode := false }}
|
||||
{{- if $hasAccount }}
|
||||
{{- $acctID = .Identity.Account.AccountID }}
|
||||
{{- $mockMode = .Accounts.GetMockMode $acctID }}
|
||||
{{- end }}
|
||||
{{- $mockMode := .MockMode }}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
@@ -63,6 +62,11 @@
|
||||
|
||||
flex
|
||||
justify-center
|
||||
|
||||
{{ if .MockMode }}
|
||||
border-[2px]
|
||||
border-[gray]
|
||||
{{ end }}
|
||||
"{{ end }}
|
||||
|
||||
{{ define "navbar-ul-class" }}class="
|
||||
@@ -108,7 +112,7 @@
|
||||
>
|
||||
<ul
|
||||
hx-swap="morph:innerHTML"
|
||||
{{ template "navbar-ul-class" }}
|
||||
{{ template "navbar-ul-class" . }}
|
||||
>
|
||||
{{- if not $loggedIn }}
|
||||
|
||||
@@ -177,7 +181,7 @@
|
||||
<nav {{ template "navbar-class" . }}>
|
||||
<ul
|
||||
hx-swap="morph:innerHTML"
|
||||
{{ template "navbar-ul-class" }}
|
||||
{{ template "navbar-ul-class" . }}
|
||||
>
|
||||
{{ template "navbar-link" (props
|
||||
"Href" (printf "/ui/accounts/%d/shops" $acctID)
|
||||
@@ -198,7 +202,7 @@
|
||||
<nav {{ template "navbar-class" . }}>
|
||||
<ul
|
||||
hx-swap="morph:innerHTML"
|
||||
{{ template "navbar-ul-class" }}
|
||||
{{ template "navbar-ul-class" . }}
|
||||
>
|
||||
{{ template "navbar-link" (props
|
||||
"Href" (printf "/ui/accounts/%d/inventory" $acctID)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
{{- $acctID := .Identity.Account.AccountID }}
|
||||
|
||||
{{- $platform := .Platform }}
|
||||
{{- if not $platform }}
|
||||
{{- $platform = .Request.URL.Query.Get "platform" }}
|
||||
{{- end }}
|
||||
|
||||
{{- $shopID := .ShopID }}
|
||||
{{- if not $shopID }}
|
||||
{{- $shopID = .Request.URL.Query.Get "shop-id" }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
<label for="shop-selector">
|
||||
Select a Shop
|
||||
</label>
|
||||
<select
|
||||
id="shop-selector"
|
||||
hx-swap=""
|
||||
hx-get="/ui/accounts/{{$acctID}}/reports/mock"
|
||||
hx-vals="js:{
|
||||
platform: console.log(event.target.value.replace(/-.*/, '')) || event.target.value.replace(/-.*/, ''),
|
||||
'shop-id': console.log(event.target.value.replace(/[^-]*-/, '')) || event.target.value.replace(/[^-]*-/, ''),
|
||||
}"
|
||||
hx-push-url="true"
|
||||
hx-target="body"
|
||||
>
|
||||
{{- range $shop := .Accounts.GetMockShops $acctID }}
|
||||
{{- $isSelected := and (eq $platform $shop.Platform) (eq $shopID $shop.ShopID) }}
|
||||
<option
|
||||
value="{{ $shop.Platform }}-{{ $shop.ShopID }}"
|
||||
{{ if $isSelected }}selected{{end}}
|
||||
>
|
||||
{{ $shop.Name }}
|
||||
</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<h3 class="m-[1em]">
|
||||
Platform: {{ $platform }}
|
||||
</h3>
|
||||
|
||||
{{- $evts := "" }}
|
||||
{{- if and $platform $shopID }}
|
||||
{{- $parsedPlatform := parsePlatform $platform }}
|
||||
{{- $evts = .Reports.GetRawShopEvents $acctID $parsedPlatform $shopID }}
|
||||
{{- end }}
|
||||
|
||||
<table id="raw-event-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Time</td>
|
||||
{{/*<td>EventID</td>*/}}
|
||||
<td>Event</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{- if $evts }}
|
||||
{{- range $evt := $evts }}
|
||||
<tr>
|
||||
<td>{{$evt.EventTimestamp}}</td>
|
||||
{{/*<td>{{$evt.EventID}}</td>*/}}
|
||||
<td>{{prettyPrintJSON $evt.RawPayload}}</td>
|
||||
</tr>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,3 +1,48 @@
|
||||
<h1>
|
||||
Simulations
|
||||
{{- $acctID := .Identity.Account.AccountID -}}
|
||||
{{- $shops := .Accounts.GetMockShops $acctID -}}
|
||||
{{- $formSelections := .Accounts.GetMockEventFormValues $acctID -}}
|
||||
|
||||
{{- $saleShopListings := "" }}
|
||||
{{- if $formSelections.SaleShopID }}
|
||||
{{ $saleShopListings = .Accounts.GetMockListingsForShop $acctID $formSelections.SalePlatform $formSelections.SaleShopID }}
|
||||
{{- end }}
|
||||
{{- $refundShopListings := "" }}
|
||||
{{- if $formSelections.RefundShopID }}
|
||||
{{ $refundShopListings = .Accounts.GetMockListingsForShop $acctID $formSelections.SalePlatform $formSelections.RefundShopID }}
|
||||
{{- end }}
|
||||
{{- $setInventoryShopListings := "" }}
|
||||
{{- if $formSelections.CountShopID }}
|
||||
{{ $setInventoryShopListings = .Accounts.GetMockListingsForShop $acctID $formSelections.SalePlatform $formSelections.CountShopID }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
<h1 class="text-center my-[0.5em]">
|
||||
Simulate
|
||||
</h1>
|
||||
|
||||
|
||||
{{/* SALES */}}
|
||||
{{ component (printf "/accounts/%d/simulations/sales-form" $acctID)
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $formSelections.SalePlatform
|
||||
"SelectedShopID" $formSelections.SaleShopID
|
||||
"Listings" $saleShopListings
|
||||
}}
|
||||
|
||||
|
||||
{{/* REFUNDS */}}
|
||||
{{ component (printf "/accounts/%d/simulations/refund-form" $acctID)
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $formSelections.RefundPlatform
|
||||
"SelectedShopID" $formSelections.RefundShopID
|
||||
"Listings" $refundShopListings
|
||||
}}
|
||||
|
||||
|
||||
{{/* SET INVENTORY */}}
|
||||
{{ component (printf "/accounts/%d/simulations/set-inventory-form" $acctID)
|
||||
"Shops" $shops
|
||||
"SelectedPlatform" $formSelections.CountPlatform
|
||||
"SelectedShopID" $formSelections.CountShopID
|
||||
"Listings" $setInventoryShopListings
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user