|
|
@@ -1,8 +1,8 @@
|
|
|
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
|
|
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
|
|
|
import { wrapHandler, logError } from '../_shared/error-handler.ts'
|
|
|
-import { fetchProducts, fetchOrders, fetchCustomers } from '../_shared/shoprenter-client.ts'
|
|
|
-import { formatFirstValidPhone, detectCountryCode } from '../_shared/phone-formatter.ts'
|
|
|
+import { fetchProducts } from '../_shared/shoprenter-client.ts'
|
|
|
+import { detectCountryCode } from '../_shared/phone-formatter.ts'
|
|
|
import {
|
|
|
collectionExists,
|
|
|
createCollection,
|
|
|
@@ -375,9 +375,8 @@ serve(wrapHandler('shoprenter-sync', async (req) => {
|
|
|
})
|
|
|
|
|
|
const syncStats = {
|
|
|
- products: { synced: 0, errors: 0 },
|
|
|
- orders: { synced: 0, errors: 0 },
|
|
|
- customers: { synced: 0, errors: 0 }
|
|
|
+ products: { synced: 0, errors: 0 }
|
|
|
+ // Note: orders and customers removed for GDPR compliance (migration 20251031_160300)
|
|
|
}
|
|
|
|
|
|
// supabaseAdmin already created above, reuse it
|
|
|
@@ -462,156 +461,22 @@ serve(wrapHandler('shoprenter-sync', async (req) => {
|
|
|
syncStats.products.errors++
|
|
|
}
|
|
|
|
|
|
- // Sync Orders
|
|
|
- let orderSyncError: Error | null = null
|
|
|
- try {
|
|
|
- console.log('[ShopRenter] Syncing orders...')
|
|
|
- let page = 0 // ShopRenter API uses zero-based pagination
|
|
|
- let hasMore = true
|
|
|
- const limit = 50
|
|
|
-
|
|
|
- while (hasMore) {
|
|
|
- const ordersData = await fetchOrders(storeId, page, limit)
|
|
|
-
|
|
|
- if (ordersData.items && ordersData.items.length > 0) {
|
|
|
- const ordersToCache = ordersData.items.map((order: any) => ({
|
|
|
- store_id: storeId,
|
|
|
- shoprenter_order_id: order.id,
|
|
|
- order_number: order.order_number || order.number || order.id,
|
|
|
- status: order.status,
|
|
|
- total: parseFloat(order.total) || 0,
|
|
|
- currency: order.currency || 'HUF',
|
|
|
- customer_name: order.customer_name || `${order.customer?.firstname || ''} ${order.customer?.lastname || ''}`.trim() || null,
|
|
|
- customer_email: order.customer_email || order.customer?.email || null,
|
|
|
- customer_phone: formatFirstValidPhone([
|
|
|
- order.customer_phone,
|
|
|
- order.customer?.phone,
|
|
|
- order.billing_address?.phone,
|
|
|
- order.shipping_address?.phone
|
|
|
- ], countryCode),
|
|
|
- line_items: order.items || order.line_items || [],
|
|
|
- billing_address: order.billing_address || null,
|
|
|
- shipping_address: order.shipping_address || null,
|
|
|
- order_created_at: order.created_at || order.date_created || new Date().toISOString(),
|
|
|
- raw_data: order,
|
|
|
- last_synced_at: new Date().toISOString()
|
|
|
- }))
|
|
|
-
|
|
|
- const { error: upsertError } = await supabaseAdmin
|
|
|
- .from('shoprenter_orders_cache')
|
|
|
- .upsert(ordersToCache, {
|
|
|
- onConflict: 'store_id,shoprenter_order_id'
|
|
|
- })
|
|
|
-
|
|
|
- if (upsertError) {
|
|
|
- console.error('[ShopRenter] Error caching orders:', upsertError)
|
|
|
- syncStats.orders.errors += ordersToCache.length
|
|
|
- } else {
|
|
|
- syncStats.orders.synced += ordersToCache.length
|
|
|
- }
|
|
|
-
|
|
|
- // Check if there are more pages
|
|
|
- if (ordersData.pagination && ordersData.pagination.total) {
|
|
|
- const totalPages = Math.ceil(ordersData.pagination.total / limit)
|
|
|
- hasMore = page < totalPages - 1 // Zero-based, so last page is totalPages - 1
|
|
|
- } else {
|
|
|
- hasMore = ordersData.items.length === limit
|
|
|
- }
|
|
|
-
|
|
|
- page++
|
|
|
- } else {
|
|
|
- hasMore = false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- console.log(`[ShopRenter] Orders synced: ${syncStats.orders.synced}`)
|
|
|
- } catch (error) {
|
|
|
- console.error('[ShopRenter] Order sync error:', error)
|
|
|
- orderSyncError = error as Error
|
|
|
- syncStats.orders.errors++
|
|
|
- }
|
|
|
-
|
|
|
- // Sync Customers
|
|
|
- let customerSyncError: Error | null = null
|
|
|
- try {
|
|
|
- console.log('[ShopRenter] Syncing customers...')
|
|
|
- let page = 0 // ShopRenter API uses zero-based pagination
|
|
|
- let hasMore = true
|
|
|
- const limit = 50
|
|
|
-
|
|
|
- while (hasMore) {
|
|
|
- const customersData = await fetchCustomers(storeId, page, limit)
|
|
|
-
|
|
|
- if (customersData.items && customersData.items.length > 0) {
|
|
|
- const customersToCache = customersData.items.map((customer: any) => ({
|
|
|
- store_id: storeId,
|
|
|
- shoprenter_customer_id: customer.id,
|
|
|
- email: customer.email,
|
|
|
- first_name: customer.firstname,
|
|
|
- last_name: customer.lastname,
|
|
|
- phone: formatFirstValidPhone([
|
|
|
- customer.phone,
|
|
|
- customer.billing_address?.phone,
|
|
|
- customer.shipping_address?.phone
|
|
|
- ], countryCode),
|
|
|
- billing_address: customer.billing_address || null,
|
|
|
- shipping_address: customer.shipping_address || null,
|
|
|
- orders_count: customer.orders_count || 0,
|
|
|
- total_spent: parseFloat(customer.total_spent) || 0,
|
|
|
- raw_data: customer,
|
|
|
- last_synced_at: new Date().toISOString()
|
|
|
- }))
|
|
|
-
|
|
|
- const { error: upsertError } = await supabaseAdmin
|
|
|
- .from('shoprenter_customers_cache')
|
|
|
- .upsert(customersToCache, {
|
|
|
- onConflict: 'store_id,shoprenter_customer_id'
|
|
|
- })
|
|
|
-
|
|
|
- if (upsertError) {
|
|
|
- console.error('[ShopRenter] Error caching customers:', upsertError)
|
|
|
- syncStats.customers.errors += customersToCache.length
|
|
|
- } else {
|
|
|
- syncStats.customers.synced += customersToCache.length
|
|
|
- }
|
|
|
-
|
|
|
- // Check if there are more pages
|
|
|
- if (customersData.pagination && customersData.pagination.total) {
|
|
|
- const totalPages = Math.ceil(customersData.pagination.total / limit)
|
|
|
- hasMore = page < totalPages - 1 // Zero-based, so last page is totalPages - 1
|
|
|
- } else {
|
|
|
- hasMore = customersData.items.length === limit
|
|
|
- }
|
|
|
-
|
|
|
- page++
|
|
|
- } else {
|
|
|
- hasMore = false
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- console.log(`[ShopRenter] Customers synced: ${syncStats.customers.synced}`)
|
|
|
- } catch (error) {
|
|
|
- console.error('[ShopRenter] Customer sync error:', error)
|
|
|
- customerSyncError = error as Error
|
|
|
- syncStats.customers.errors++
|
|
|
- }
|
|
|
+ // Note: Customer and Order caching removed for GDPR compliance (migration 20251031_160300)
|
|
|
+ // Customer/order data is now accessed in real-time via webshop-data-api endpoint
|
|
|
+ console.log('[ShopRenter] Skipping customer/order caching (GDPR compliance - use real-time API access)')
|
|
|
|
|
|
// Update BOTH stores table and store_sync_config to maintain consistency
|
|
|
const syncCompletedAt = new Date().toISOString()
|
|
|
|
|
|
- // Check if any critical errors occurred
|
|
|
- const hasErrors = productSyncError || orderSyncError || customerSyncError
|
|
|
- const totalErrors = syncStats.products.errors + syncStats.orders.errors + syncStats.customers.errors
|
|
|
- const totalSynced = syncStats.products.synced + syncStats.orders.synced + syncStats.customers.synced
|
|
|
+ // Check if any critical errors occurred (only products now, customer/order removed for GDPR)
|
|
|
+ const hasErrors = productSyncError !== null
|
|
|
+ const totalErrors = syncStats.products.errors
|
|
|
+ const totalSynced = syncStats.products.synced
|
|
|
|
|
|
// Build error message if any errors occurred
|
|
|
let errorMessage: string | null = null
|
|
|
- if (hasErrors) {
|
|
|
- const errorParts: string[] = []
|
|
|
- if (productSyncError) errorParts.push(`Products: ${productSyncError.message}`)
|
|
|
- if (orderSyncError) errorParts.push(`Orders: ${orderSyncError.message}`)
|
|
|
- if (customerSyncError) errorParts.push(`Customers: ${customerSyncError.message}`)
|
|
|
- errorMessage = errorParts.join('; ')
|
|
|
+ if (hasErrors && productSyncError) {
|
|
|
+ errorMessage = `Products: ${productSyncError.message}`
|
|
|
}
|
|
|
|
|
|
// Update stores table (for Web UI display)
|