New order rows table (#238)

Co-authored-by: Niklas Fondberg <niklas.fondberg@photowall.se>
Co-authored-by: Rikard Bartholf <rikard@bartholf.nu>
This commit is contained in:
Fredrik Ringqvist
2022-01-20 06:04:59 +01:00
committed by GitHub
co-authored by Niklas Fondberg Rikard Bartholf
parent cbffaaeee7
commit 8ef219452f
5 changed files with 459 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
-- Create new order rows table
CREATE TYPE order_row_status AS ENUM (
'no_status',
'process',
'error',
'print',
'packed',
'cancelled',
'sent'
);
CREATE TYPE order_row_type AS ENUM (
'discount',
'fee',
'print',
'stock',
'sample',
'refund'
);
-- TODO: new-order: how to deal with inquiries???
CREATE TYPE order_row_sub_type AS ENUM (
'no_subtype',
'wallpaper',
'canvas',
'poster',
'framed_print',
'inquiry_wallpaper',
'inquiry_canvas',
'inquiry_poster',
'inquiry_framed_print',
'retouch_fee',
'contract_customer_discount',
'discount_code',
'wallpaper_kit',
'canvas_frame',
'sample',
'admin_product'
);
-- Start sequence at 1 million for orders id table
ALTER SEQUENCE orders_id_seq RESTART WITH 1000000;
CREATE TABLE order_rows (
id int GENERATED ALWAYS AS IDENTITY (START WITH 2500000) PRIMARY KEY,
type order_row_type NOT NULL,
sub_type order_row_sub_type NOT NULL,
status order_row_status DEFAULT 'no_status',
order_id int REFERENCES orders (id),
designer_id int REFERENCES designers (designerid),
inserted timestamp with time zone DEFAULT now(),
updated timestamp with time zone,
price numeric NOT NULL,
commission_amount numeric DEFAULT 0.0,
data JSONB
);
COMMENT ON COLUMN order_rows.price IS 'Price without VAT';
CREATE TRIGGER updated_timestamp BEFORE UPDATE ON public.order_rows FOR EACH ROW EXECUTE PROCEDURE public.updated_timestamp();
CREATE INDEX ON order_rows(order_id);
CREATE INDEX ON order_rows(designer_id);
CREATE INDEX ON order_rows(status);
CREATE INDEX ON order_rows(type);
CREATE INDEX ON order_rows(sub_type);
CREATE INDEX ON order_rows((data->>'inquiryid'));
CREATE INDEX ON order_rows((data->>'code'));
CREATE INDEX ON order_rows((data->>'artNo'));
CREATE INDEX ON order_rows((data->>'group'));
-- added column order_row_id to samples
ALTER TABLE samples ADD column IF NOT EXISTS order_row_id int REFERENCES order_rows (id);
+130
View File
@@ -0,0 +1,130 @@
INSERT INTO order_rows (id, type, sub_type, status, order_id, designer_id, price, commission_amount, data, inserted)
OVERRIDING SYSTEM VALUE
SELECT rowid, itype::order_row_type, isubtype::order_row_sub_type, status::order_row_status, order_id, designer_id, price, commission_amount, data, inserted
FROM (
SELECT orow.orderid order_id,
orow.rowid,
orow.inserted,
(odata.odata ->> 'designerId')::int designer_id,
(odata.odata ->> 'commission_amount')::float commission_amount,
CASE
-- next line are for admin products
WHEN (odata.odata ->> 'type') = 'stock' AND (odata.odata ->> 'path') is NULL THEN 'fee'
WHEN (odata.odata ->> 'modifier') LIKE '%Discount%' THEN 'discount'
WHEN (odata.odata ->> 'modifier') LIKE '%discount%' THEN 'discount'
WHEN (odata.odata ->> 'modifier') LIKE '%Fee%' THEN 'fee'
WHEN (odata.odata ->> 'path') = 'sample' THEN 'sample'
WHEN (odata.odata ->> 'type') = 'stock' THEN 'stock'
WHEN (odata.odata ->> 'status') = 'cancelled' THEN 'refund'
ELSE 'print'
END itype,
CASE
-- next line are for admin products
WHEN (odata.odata ->> 'type') = 'stock' AND (odata.odata ->> 'path') is NULL THEN 'admin_product'
WHEN (odata.odata ->> 'modifier') = 'contractCustomerDiscount' THEN 'contract_customer_discount'
WHEN (odata.odata ->> 'modifier') = 'discount' THEN 'discount_code'
WHEN (odata.odata ->> 'path') = 'sample' THEN 'sample'
WHEN (odata.odata ->> 'path') = 'doityourselfframe' THEN 'canvas_frame'
WHEN (odata.odata ->> 'path') = 'wallpaper-kit' THEN 'wallpaper_kit'
WHEN (odata.odata ->> 'group') LIKE '%wallpaper' AND (odata.odata ->> 'inquiryid') IS NULL THEN 'wallpaper'
WHEN (odata.odata ->> 'group') LIKE 'canvas' AND (odata.odata ->> 'inquiryid') IS NULL THEN 'canvas'
WHEN (odata.odata ->> 'group') LIKE 'poster' AND (odata.odata ->> 'inquiryid') IS NULL THEN 'poster'
WHEN (odata.odata ->> 'group') LIKE 'framed-print' AND (odata.odata ->> 'inquiryid') IS NULL THEN 'framed_print'
WHEN (odata.odata ->> 'group') LIKE '%wallpaper' AND (odata.odata ->> 'inquiryid') IS NOT NULL THEN 'inquiry_wallpaper'
WHEN (odata.odata ->> 'group') LIKE 'canvas' AND (odata.odata ->> 'inquiryid') IS NOT NULL THEN 'inquiry_canvas'
WHEN (odata.odata ->> 'group') LIKE 'poster' AND (odata.odata ->> 'inquiryid') IS NOT NULL THEN 'inquiry_poster'
WHEN (odata.odata ->> 'group') LIKE 'framed-print' AND (odata.odata ->> 'inquiryid') IS NOT NULL THEN 'inquiry_framed_print'
ELSE 'no_subtype'
END isubtype,
CASE
-- next line are for admin products
WHEN (odata.odata ->> 'type') = 'stock' AND (odata.odata ->> 'path') is NULL THEN 'no_status'
WHEN (odata.odata ->> 'status') = 'pack' THEN 'process'
WHEN (odata.odata ->> 'status') IS NULL THEN 'no_status'
WHEN (odata.odata ->> 'imageprocessingrejected') = 'true' THEN 'error'
WHEN (odata.odata ->> 'imagedonotprint') = 'true' THEN 'cancelled'
ELSE (odata.odata ->> 'status')
END status,
(odata.odata ->> 'price')::float price,
odata.odata - '{designerId, commission_amount, status, price}'::text[] "data"
FROM "order-rows" orow
JOIN (
SELECT od.rowid,
json_object_agg(orf.name, od.value)::jsonb AS odata
FROM "order-rows_details" od
JOIN "order-row_fields" orf
ON od.fieldid = orf.fieldid
GROUP BY 1
) odata ON orow.rowid = odata.rowid
WHERE orow.orderid IN
(
SELECT oof.orderid
FROM "order-orders_fields" oof
WHERE fieldid = 168
AND "value" = 'true'
)
) s;
UPDATE order_rows SET data = jsonb_set("data", '{commission_resale}', to_jsonb((data ->> 'commission_resale')::int)) WHERE data->>'commission_resale' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{height}', to_jsonb((data ->> 'height')::int)) WHERE data->>'height' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{inquiryid}', to_jsonb((data ->> 'inquiryid')::int)) WHERE data->>'inquiryid' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{printId}', to_jsonb((data ->> 'printId')::int)) WHERE data->>'printId' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{productId}', to_jsonb((data ->> 'productId')::int)) WHERE data->>'productId' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{resolution}', to_jsonb((data ->> 'resolution')::int)) WHERE data->>'resolution' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{stockId}', to_jsonb((data ->> 'stockId')::int)) WHERE data->>'stockId' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{width}', to_jsonb((data ->> 'width')::int)) WHERE data->>'width' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{commission}', to_jsonb((data ->> 'commission')::numeric)) WHERE data->>'commission' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{discountValue}', to_jsonb((data ->> 'discountValue')::numeric)) WHERE data->>'discountValue' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{displayHeight}', to_jsonb((data ->> 'displayHeight')::numeric)) WHERE data->>'displayHeight' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{displayWidth}', to_jsonb((data ->> 'displayWidth')::numeric)) WHERE data->>'displayWidth' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{fixedVAT}', to_jsonb((data ->> 'fixedVAT')::numeric)) WHERE data->>'fixedVAT' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{height_mm}', to_jsonb((data ->> 'height_mm')::numeric)) WHERE data->>'height_mm' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{imageHeight}', to_jsonb((data ->> 'imageHeight')::int)) WHERE data->>'imageHeight' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{imageWidth}', to_jsonb((data ->> 'imageWidth')::int)) WHERE data->>'imageWidth' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{percent}', to_jsonb((data ->> 'percent')::numeric)) WHERE data->>'percent' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{retouch_price}', to_jsonb((data ->> 'retouch_price')::numeric)) WHERE data->>'retouch_price' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{VAT}', to_jsonb((data ->> 'VAT')::numeric)) WHERE data->>'VAT' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{x}', to_jsonb((data ->> 'x')::numeric)) WHERE data->>'x' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{y}', to_jsonb((data ->> 'y')::numeric)) WHERE data->>'y' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{weight}', to_jsonb((data ->> 'weight')::numeric)) WHERE data->>'weight' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{width_mm}', to_jsonb((data ->> 'width_mm')::numeric)) WHERE data->>'width_mm' <> '';
UPDATE order_rows SET data = jsonb_set("data", '{automated}', to_jsonb(false)) WHERE data->>'automated' = '0';
UPDATE order_rows SET data = jsonb_set("data", '{automated}', to_jsonb(true)) WHERE data->>'automated' = '1';
UPDATE order_rows SET data = jsonb_set("data", '{framed}', to_jsonb(false)) WHERE data->>'framed' = '0';
UPDATE order_rows SET data = jsonb_set("data", '{framed}', to_jsonb(true)) WHERE data->>'framed' = '1';
UPDATE order_rows SET data = jsonb_set("data", '{uploaded}', to_jsonb(false)) WHERE data->>'uploaded' = '0';
UPDATE order_rows SET data = jsonb_set("data", '{uploaded}', to_jsonb(true)) WHERE data->>'uploaded' = '1';
UPDATE order_rows SET data = jsonb_set("data", '{imagedonotprint}', to_jsonb(false)) WHERE data->>'imagedonotprint' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{imagedonotprint}', to_jsonb(true)) WHERE data->>'imagedonotprint' = 'true';
UPDATE order_rows SET data = jsonb_set("data", '{imageprocessed}', to_jsonb(false)) WHERE data->>'imageprocessed' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{imageprocessed}', to_jsonb(true)) WHERE data->>'imageprocessed' = 'true';
UPDATE order_rows SET data = jsonb_set("data", '{imageprocessingrejected}', to_jsonb(false)) WHERE data->>'imageprocessingrejected' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{imageprocessingrejected}', to_jsonb(true)) WHERE data->>'imageprocessingrejected' = 'true';
UPDATE order_rows SET data = jsonb_set("data", '{mirrored}', to_jsonb(false)) WHERE data->>'mirrored' = '0';
UPDATE order_rows SET data = jsonb_set("data", '{mirrored}', to_jsonb(true)) WHERE data->>'mirrored' = '1';
UPDATE order_rows SET data = jsonb_set("data", '{no_shipping}', to_jsonb(false)) WHERE data->>'no_shipping' = 'False';
UPDATE order_rows SET data = jsonb_set("data", '{no_shipping}', to_jsonb(true)) WHERE data->>'no_shipping' = 'True';
UPDATE order_rows SET data = jsonb_set("data", '{packed}', to_jsonb(false)) WHERE data->>'packed' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{packed}', to_jsonb(true)) WHERE data->>'packed' = 'true';
UPDATE order_rows SET data = jsonb_set("data", '{process}', to_jsonb(false)) WHERE data->>'process' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{process}', to_jsonb(true)) WHERE data->>'process' = 'true';
UPDATE order_rows SET data = jsonb_set("data", '{edge_fixed}', to_jsonb(false)) WHERE data->>'edge_fixed' = 'false';
UPDATE order_rows SET data = jsonb_set("data", '{edge_fixed}', to_jsonb(true)) WHERE data->>'edge_fixed' = 'true';
-- Special case of a job row from 2015 that appeared in processing list
UPDATE order_rows SET type = 'refund' WHERE id = 303385;
+13
View File
@@ -0,0 +1,13 @@
-- migrate email and phone to addresses table
ALTER TABLE addresses ADD column IF NOT EXISTS email text;
ALTER TABLE addresses ADD column IF NOT EXISTS phone text;
UPDATE addresses SET phone = oo.phone, email = oo.email FROM orders oo WHERE addresses.id = oo.billing_address_id;
UPDATE addresses SET phone = oo.delivery_phone, email = oo.delivery_email FROM orders oo WHERE addresses.id = oo.delivery_address_id;
-- ALTER table orders drop column phone;
-- ALTER table orders drop column email;
-- ALTER table orders drop column delivery_email;
-- ALTER table orders drop column delivery_phone;
+234
View File
@@ -0,0 +1,234 @@
-- Adapt to orders and order_rows tables
--
DROP VIEW IF EXISTS v_analytics_contract_customer_discounts;
CREATE VIEW v_analytics_contract_customer_discounts AS
SELECT
order_rows.order_id as orderid,
order_rows.id as rowid,
orders.delivery_vat as vat,
order_rows.price,
round((order_rows.data->>'percent')::numeric / 100 , 2) AS percent
FROM order_rows
JOIN orders on orders.id = order_rows.order_id
WHERE order_rows.sub_type = 'contract_customer_discount';
GRANT SELECT ON v_analytics_contract_customer_discounts TO datastudio;
--
DROP VIEW IF EXISTS v_analytics_discounts;
CREATE VIEW v_analytics_discounts AS
SELECT
order_rows.order_id as orderid,
order_rows.id as rowid,
order_rows.data->>'type' as type,
orders.delivery_vat as vat,
(abs(price / exchange_rate))::float AS price_sek,
order_rows.data->>'code' as code,
order_rows.data->>'no_shipping' as no_shipping
from order_rows
JOIN orders on orders.id = order_rows.order_id
WHERE order_rows.sub_type = 'discount_code';
GRANT SELECT ON v_analytics_discounts TO datastudio;
--
DROP VIEW IF EXISTS v_analytics_inquiries;
CREATE VIEW v_analytics_inquiries AS
SELECT inquiries.inquiryid,
inquiries.inserted::date AS inserted,
inquiries.updated::date AS updated,
inquiries.company,
inquiries.firstname,
inquiries.lastname AS email,
inquiries.market_id,
inquiries.locale_id AS product_group,
inquiries.price_m2,
inquiries.price_effect,
inquiries.price_retouch,
inquiries.width,
inquiries.height,
inquiries."artNo",
inquiries.materialid,
inquiries.zendesk_ticket,
order_rows.id AS order_row_id,
order_rows.order_id AS order_id
FROM inquiries
LEFT JOIN order_rows on order_rows.data->>'inquiryid' = inquiries.inquiryid::text
ORDER BY (inquiries.inserted::date) DESC;
GRANT SELECT ON v_analytics_inquiries to datastudio;
--
DROP VIEW IF EXISTS v_analytics_order_rows;
CREATE VIEW v_analytics_order_rows AS
SELECT
CASE
WHEN orders.market IS NULL THEN 'Unknown'
WHEN orders.market = 'GB' THEN 'Photowall UK'
WHEN orders.market = 'GLOBAL' THEN 'Photowall OTHER'
ELSE 'Photowall ' || orders.market
END AS account,
order_rows.order_id as orderid,
order_rows.id as rowid,
orders.inserted::date AS orderdate,
order_rows.data->>'artNo' AS artno,
order_rows.data->>'productId' AS productid,
order_rows.data->>'name' AS name,
order_rows.data->>'inquiryid' AS inquiryid,
CASE
WHEN order_rows.type = 'sample' THEN 'Sample'
ELSE order_rows.data->>'group'
END AS type,
order_rows.data->>'material' as material,
COALESCE((order_rows.data->>'width_mm')::float / 10::float, (order_rows.data->>'width')::float) AS width,
COALESCE((order_rows.data->>'height_mm')::float / 10::float, (order_rows.data->>'height')::float) AS height,
CASE
WHEN order_rows.status = 'process' THEN 'Ready for processing'
WHEN order_rows.status = 'print' THEN 'Ready for packing'
WHEN order_rows.status = 'packed' THEN 'Ready for sending'
WHEN order_rows.status = 'sent' THEN 'Sent'
ELSE 'Unknown'
END AS status,
order_rows.data->>'commission' AS commission_percent,
round((order_rows.data->>'height')::float) AS commission_amount,
order_rows.data->>'discountType' AS discount_type,
order_rows.data->>'discountValue' AS discount_value,
CASE
WHEN order_rows.data->>'discountType' <> '%' THEN (order_rows.data->>'discountValue')::float / orders.exchange_rate
ELSE NULL::float
END AS discount_amount_sek,
orders.currency::TEXT AS order_currency,
order_rows.data->>'designer' AS designer,
(order_rows.price / orders.exchange_rate)::float AS item_value_sek,
order_rows.data->>'framed' AS canvas_frame,
order_rows.data->>'posterHanger' as poster_hanger,
order_rows.data->>'frame_color' as framed_print_frame,
order_rows.price::float AS price,
orders.delivery_vat AS vat
FROM order_rows
LEFT JOIN orders ON orders.id = order_rows.order_id
WHERE order_rows.type in ('print', 'stock');
GRANT SELECT ON v_analytics_order_rows to datastudio;
--
DROP VIEW IF EXISTS v_analytics_orders_not_delivered;
CREATE VIEW v_analytics_orders_not_delivered AS
SELECT
CASE
WHEN orders.market IS NULL THEN 'Unknown'
WHEN orders.market = 'GB' THEN 'Photowall UK'
WHEN orders.market = 'GLOBAL' THEN 'Photowall OTHER'
ELSE 'Photowall ' || orders.market
END AS account,
orders.inserted::date AS orderdate,
orders.id as orderid,
md5(billing_address.first_name || 'secret') AS first_name,
md5(billing_address.last_name || 'secret') AS last_name,
md5(billing_address.company_name || 'secret') AS company,
md5(billing_address.address1 || 'secret') AS address,
billing_address.zipcode AS postal_code,
billing_address.city,
billing_address.country_code AS country,
md5(billing_address.email || 'secret') AS email,
order_sum::float / exchange_rate::float AS order_value_sek
FROM orders
LEFT JOIN addresses billing_address ON billing_address.id = orders.billing_address_id
WHERE confirmed = 1 AND delivered = 0 AND canceled = 0 AND paid = 1;
GRANT SELECT ON v_analytics_orders_not_delivered to datastudio;
--
DROP VIEW IF EXISTS v_analytics_orders_rows_not_delivered;
CREATE VIEW v_analytics_orders_rows_not_delivered AS
SELECT order_rows.id AS order_row_id,
orders.id as orderid,
orders.inserted AS order_date,
order_rows.data->>'group' AS product_group,
order_rows.data->>'artNo' AS artno,
order_rows.status::TEXT AS status,
order_rows.data->>'name' AS name,
order_rows.data->>'material' AS material
FROM order_rows
JOIN orders ON order_rows.order_id = orders.id
WHERE order_rows.type in ('print', 'stock')
AND orders.confirmed = 1
AND orders.delivered = 0
AND orders.canceled = 0
AND orders.paid = 1;
GRANT SELECT ON v_analytics_orders_rows_not_delivered to datastudio;
-- Update view
CREATE OR REPLACE VIEW public.v_analytics_orders2 AS
SELECT orders.id AS order_id,
orders.inserted AS order_date,
orders.delivered,
orders.newsletter,
orders.credit_invoice,
orders.canceled,
orders.reminder,
orders.delivered_date,
orders.country_code,
orders.language,
orders.delivery_country_code,
orders.delivery_method,
orders.delivery_price,
orders.customer_type,
orders.payment_type,
orders.currency,
orders.exchange_rate,
orders.exchange_rate_eur,
orders.invoice_id,
orders.contract_customer_id,
orders.vat_number,
orders.cancels_order_id,
orders.cancelled_by_order_id,
orders.reseller_store,
orders.order_sum,
orders.order_sum / orders.exchange_rate AS order_sum_sek,
billing_address.email,
billing_address.phone,
billing_address.address1 AS billing_address_address1,
billing_address.address2 AS billing_address_address2,
billing_address.company_name AS billing_address_company_name,
billing_address.country_code AS billing_address_country_code,
billing_address.city AS billing_address_city,
billing_address.zipcode AS billing_address_zipcode,
billing_address.first_name AS billing_address_first_name,
billing_address.last_name AS billing_address_last_name,
billing_address.state AS billing_address_state,
delivery_address.address1 AS delivery_address_address1,
delivery_address.address2 AS delivery_address_address2,
delivery_address.company_name AS delivery_address_company_name,
delivery_address.country_code AS delivery_address_country_code,
delivery_address.city AS delivery_address_city,
delivery_address.zipcode AS delivery_address_zipcode,
delivery_address.first_name AS delivery_address_first_name,
delivery_address.last_name AS delivery_address_last_name,
delivery_address.state AS delivery_address_state
FROM orders
JOIN addresses billing_address ON billing_address.id = orders.billing_address_id
LEFT JOIN addresses delivery_address ON delivery_address.id = orders.delivery_address_id
WHERE orders.paid = 1;
GRANT SELECT ON v_analytics_orders2 TO datastudio;
-- Not used
-- DROP VIEW IF EXISTS v_analytics_orders;
-- DROP VIEW IF EXISTS v_order_rows;
-- DROP VIEW IF EXISTS v_orders;
-- DROP MATERIALIZED VIEW IF EXISTS v_sales_report;
-- DROP MATERIALIZED VIEW IF EXISTS test;
+5
View File
@@ -0,0 +1,5 @@
-- remove order-orders foreign key from invoices
ALTER TABLE invoices DROP CONSTRAINT order_fk;
ALTER TABLE ONLY public.invoices ADD CONSTRAINT order_fk FOREIGN KEY (order_id) REFERENCES public.orders(id);