- Add Apollo Client for Saleor GraphQL API - Create GraphQL fragments (Product, Variant, Checkout) - Create GraphQL queries (Products, Checkout) - Create GraphQL mutations (Checkout operations) - Add TypeScript types for Saleor entities - Add product helper functions - Install @apollo/client and graphql dependencies Part of WordPress/WooCommerce → Saleor migration
202 lines
8.2 KiB
SQL
202 lines
8.2 KiB
SQL
-- =====================================================
|
|
-- WooCommerce GUEST Checkout to Saleor Migration
|
|
-- =====================================================
|
|
-- For stores without customer accounts - all data is in orders
|
|
|
|
-- Since there are no customer accounts, we create users from order data
|
|
-- Strategy: Create a Saleor user for each unique email in orders
|
|
|
|
-- Step 1: Create mapping table for email-based customers
|
|
CREATE TABLE IF NOT EXISTS wc_guest_customer_mapping (
|
|
email VARCHAR(255) PRIMARY KEY,
|
|
saleor_user_id UUID,
|
|
first_name VARCHAR(255),
|
|
last_name VARCHAR(255),
|
|
phone VARCHAR(255),
|
|
order_count INTEGER DEFAULT 0,
|
|
total_spent DECIMAL(12,2) DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- Step 2: Export unique customers from orders (no wp_users needed!)
|
|
-- Run this on WordPress/MariaDB:
|
|
/*
|
|
SELECT DISTINCT
|
|
meta_email.meta_value as email,
|
|
MAX(meta_first.meta_value) as first_name,
|
|
MAX(meta_last.meta_value) as last_name,
|
|
MAX(meta_phone.meta_value) as phone,
|
|
COUNT(DISTINCT p.ID) as order_count,
|
|
SUM(CAST(meta_total.meta_value AS DECIMAL(12,2))) as total_spent
|
|
FROM wp_posts p
|
|
JOIN wp_postmeta meta_email ON p.ID = meta_email.post_id AND meta_email.meta_key = '_billing_email'
|
|
LEFT JOIN wp_postmeta meta_first ON p.ID = meta_first.post_id AND meta_first.meta_key = '_billing_first_name'
|
|
LEFT JOIN wp_postmeta meta_last ON p.ID = meta_last.post_id AND meta_last.meta_key = '_billing_last_name'
|
|
LEFT JOIN wp_postmeta meta_phone ON p.ID = meta_phone.post_id AND meta_phone.meta_key = '_billing_phone'
|
|
LEFT JOIN wp_postmeta meta_total ON p.ID = meta_total.post_id AND meta_total.meta_key = '_order_total'
|
|
WHERE p.post_type = 'shop_order'
|
|
AND meta_email.meta_value IS NOT NULL
|
|
AND meta_email.meta_value != ''
|
|
GROUP BY meta_email.meta_value
|
|
ORDER BY order_count DESC;
|
|
*/
|
|
|
|
-- Step 3: Insert guest customers into Saleor
|
|
-- For each unique email, create a user account
|
|
|
|
/*
|
|
WITH new_guest_user AS (
|
|
INSERT INTO account_user (
|
|
id, email, first_name, last_name,
|
|
is_staff, is_active, date_joined,
|
|
last_login, password
|
|
) VALUES (
|
|
gen_random_uuid(),
|
|
'customer@example.com', -- from order billing_email
|
|
'John', -- from order billing_first_name
|
|
'Doe', -- from order billing_last_name
|
|
false,
|
|
true,
|
|
NOW(), -- use first order date if available
|
|
NULL,
|
|
'!' -- unusable password - customer must set via password reset
|
|
)
|
|
RETURNING id, email
|
|
)
|
|
INSERT INTO wc_guest_customer_mapping (email, saleor_user_id, first_name, last_name)
|
|
SELECT email, id, 'John', 'Doe' FROM new_guest_user;
|
|
*/
|
|
|
|
-- Step 4: Create addresses from most recent order per customer
|
|
-- Get the most recent order for each email to extract address
|
|
|
|
/*
|
|
WITH latest_orders AS (
|
|
SELECT DISTINCT ON (meta_email.meta_value)
|
|
meta_email.meta_value as email,
|
|
p.ID as order_id,
|
|
p.post_date as order_date
|
|
FROM wp_posts p
|
|
JOIN wp_postmeta meta_email ON p.ID = meta_email.post_id AND meta_email.meta_key = '_billing_email'
|
|
WHERE p.post_type = 'shop_order'
|
|
ORDER BY meta_email.meta_value, p.post_date DESC
|
|
),
|
|
address_data AS (
|
|
SELECT
|
|
lo.email,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_first_name' THEN pm.meta_value END) as bill_first,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_last_name' THEN pm.meta_value END) as bill_last,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_company' THEN pm.meta_value END) as bill_company,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_address_1' THEN pm.meta_value END) as bill_addr1,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_address_2' THEN pm.meta_value END) as bill_addr2,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_city' THEN pm.meta_value END) as bill_city,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_postcode' THEN pm.meta_value END) as bill_postcode,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_country' THEN pm.meta_value END) as bill_country,
|
|
MAX(CASE WHEN pm.meta_key = '_billing_phone' THEN pm.meta_value END) as bill_phone,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_first_name' THEN pm.meta_value END) as ship_first,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_last_name' THEN pm.meta_value END) as ship_last,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_company' THEN pm.meta_value END) as ship_company,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_address_1' THEN pm.meta_value END) as ship_addr1,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_address_2' THEN pm.meta_value END) as ship_addr2,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_city' THEN pm.meta_value END) as ship_city,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_postcode' THEN pm.meta_value END) as ship_postcode,
|
|
MAX(CASE WHEN pm.meta_key = '_shipping_country' THEN pm.meta_value END) as ship_country
|
|
FROM latest_orders lo
|
|
JOIN wp_postmeta pm ON lo.order_id = pm.post_id
|
|
GROUP BY lo.email
|
|
)
|
|
-- Insert billing address and link to user
|
|
INSERT INTO account_address (id, first_name, last_name, company_name,
|
|
street_address_1, street_address_2, city, postal_code, country, phone)
|
|
SELECT
|
|
gen_random_uuid(),
|
|
bill_first, bill_last, COALESCE(bill_company, ''),
|
|
bill_addr1, COALESCE(bill_addr2, ''), bill_city,
|
|
bill_postcode, COALESCE(bill_country, 'RS'), COALESCE(bill_phone, '')
|
|
FROM address_data ad
|
|
JOIN wc_guest_customer_mapping cm ON ad.email = cm.email
|
|
WHERE cm.saleor_user_id IS NOT NULL
|
|
RETURNING id, (SELECT email FROM wc_guest_customer_mapping WHERE saleor_user_id =
|
|
(SELECT id FROM account_user WHERE id = account_address.id)); -- This needs adjustment
|
|
|
|
-- Then link addresses to users via account_user_addresses
|
|
*/
|
|
|
|
-- Alternative simpler approach: Insert order with addresses inline (no separate customer record)
|
|
-- Saleor supports orders without user accounts (guest orders)
|
|
|
|
-- =====================================================
|
|
-- SIMPLIFIED: Orders Only (No Customer Accounts)
|
|
-- =====================================================
|
|
-- If you don't want to create customer accounts at all,
|
|
-- just migrate orders as guest orders with email addresses
|
|
|
|
/*
|
|
INSERT INTO order_order (
|
|
id, created_at, updated_at, status,
|
|
user_email, -- Store email here (no user_id)
|
|
user_id, -- NULL for guest orders
|
|
currency, total_gross_amount, total_net_amount,
|
|
shipping_price_gross_amount, shipping_price_net_amount,
|
|
shipping_method_name, channel_id,
|
|
billing_address, -- JSON with full address
|
|
shipping_address, -- JSON with full address
|
|
metadata, origin,
|
|
should_refresh_prices, tax_exemption,
|
|
discount_amount, display_gross_prices,
|
|
customer_note
|
|
) VALUES (
|
|
gen_random_uuid(),
|
|
'2024-01-15 10:30:00'::timestamp,
|
|
'2024-01-15 10:30:00'::timestamp,
|
|
'FULFILLED',
|
|
'guest@example.com', -- Customer email from order
|
|
NULL, -- No user account (guest order)
|
|
'RSD',
|
|
11500.00,
|
|
10000.00,
|
|
500.00,
|
|
500.00,
|
|
'Flat Rate',
|
|
(SELECT id FROM channel_channel WHERE slug = 'default-channel'),
|
|
'{
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"street_address_1": "Kneza Milosa 10",
|
|
"city": "Belgrade",
|
|
"postal_code": "11000",
|
|
"country": "RS",
|
|
"phone": "+38164123456"
|
|
}'::jsonb,
|
|
'{
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"street_address_1": "Kneza Milosa 10",
|
|
"city": "Belgrade",
|
|
"postal_code": "11000",
|
|
"country": "RS",
|
|
"phone": "+38164123456"
|
|
}'::jsonb,
|
|
'{"woo_order_id": "12345", "guest_checkout": true}'::jsonb,
|
|
'BULK_CREATE',
|
|
false,
|
|
false,
|
|
0.00,
|
|
true,
|
|
''
|
|
);
|
|
*/
|
|
|
|
-- =====================================================
|
|
-- RECOMMENDED APPROACH: Hybrid
|
|
-- =====================================================
|
|
-- 1. Create lightweight user accounts from unique emails
|
|
-- 2. Link all orders to these accounts
|
|
-- 3. Customers can claim accounts via password reset
|
|
|
|
-- Benefits:
|
|
-- - Order history tied to email
|
|
-- - Customers can "activate" their account later
|
|
-- - Better analytics (LTV per customer)
|
|
-- - Future marketing (targeted emails)
|