This commit is contained in:
2026-01-06 23:15:24 +01:00
parent 3b5c4bdce8
commit c12c776e67
56 changed files with 30095 additions and 145 deletions

View File

@@ -0,0 +1,194 @@
#!/usr/bin/env node
/**
* Script to check WooCommerce product attributes for high-voltage cables
* This will query the API directly to see if attributes exist but weren't captured
*/
const https = require('https');
const path = require('path');
require('dotenv').config();
const CONFIG = {
url: process.env.WOOCOMMERCE_URL,
key: process.env.WOOCOMMERCE_CONSUMER_KEY,
secret: process.env.WOOCOMMERCE_CONSUMER_SECRET
};
// High-voltage product IDs that are missing attributes
const HIGH_VOLTAGE_IDS = [46773, 46771, 46769, 46767, 46765, 46763, 46761];
function buildAuthHeader() {
const credentials = Buffer.from(`${CONFIG.key}:${CONFIG.secret}`).toString('base64');
return `Basic ${credentials}`;
}
function makeRequest(endpoint) {
return new Promise((resolve, reject) => {
const url = `${CONFIG.url}/wp-json/wc/v3${endpoint}`;
const options = {
headers: {
'Authorization': buildAuthHeader(),
'Content-Type': 'application/json',
'User-Agent': 'KLZ-Attribute-Checker/1.0'
}
};
console.log(`🌐 Fetching: ${endpoint}`);
https.get(url, options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
resolve(JSON.parse(data));
} catch (e) {
resolve(data);
}
} else {
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
}
});
}).on('error', reject);
});
}
async function checkProductAttributes() {
console.log('🔍 Checking WooCommerce Product Attributes\n');
console.log('Target URL:', CONFIG.url);
console.log('Products to check:', HIGH_VOLTAGE_IDS.length);
console.log('');
const results = [];
for (const productId of HIGH_VOLTAGE_IDS) {
try {
const product = await makeRequest(`/products/${productId}`);
console.log(`\n📦 Product ID: ${productId}`);
console.log(`Name: ${product.name}`);
console.log(`SKU: ${product.sku}`);
console.log(`Type: ${product.type}`);
if (product.attributes && product.attributes.length > 0) {
console.log(`✅ Attributes found: ${product.attributes.length}`);
// Show sample attributes
product.attributes.slice(0, 5).forEach(attr => {
console.log(` - ${attr.name}: ${attr.options?.length || 0} options`);
});
if (product.attributes.length > 5) {
console.log(` ... and ${product.attributes.length - 5} more`);
}
results.push({
id: productId,
name: product.name,
hasAttributes: true,
count: product.attributes.length,
attributes: product.attributes
});
} else {
console.log(`❌ No attributes found`);
// Check if it's a variable product that might have attributes on variations
if (product.type === 'variable' && product.variations && product.variations.length > 0) {
console.log(` Variable product with ${product.variations.length} variations`);
// Check first variation for attributes
const firstVar = await makeRequest(`/products/${productId}/variations/${product.variations[0]}`);
if (firstVar.attributes && firstVar.attributes.length > 0) {
console.log(`⚠️ Variations have attributes, but parent product doesn't`);
}
}
results.push({
id: productId,
name: product.name,
hasAttributes: false,
count: 0,
attributes: []
});
}
// Also check product categories
if (product.categories && product.categories.length > 0) {
console.log(`Categories: ${product.categories.map(c => c.name).join(', ')}`);
}
} catch (error) {
console.log(`❌ Error fetching product ${productId}: ${error.message}`);
results.push({
id: productId,
name: 'Unknown',
hasAttributes: false,
count: 0,
error: error.message
});
}
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 200));
}
// Summary
console.log('\n' + '='.repeat(60));
console.log('📊 SUMMARY');
console.log('='.repeat(60));
const withAttrs = results.filter(r => r.hasAttributes);
const withoutAttrs = results.filter(r => !r.hasAttributes);
console.log(`Products checked: ${results.length}`);
console.log(`✅ With attributes: ${withAttrs.length}`);
console.log(`❌ Without attributes: ${withoutAttrs.length}`);
if (withAttrs.length > 0) {
console.log('\nProducts WITH attributes:');
withAttrs.forEach(p => {
console.log(` - ${p.name} (${p.count} attributes)`);
});
}
if (withoutAttrs.length > 0) {
console.log('\nProducts WITHOUT attributes:');
withoutAttrs.forEach(p => {
console.log(` - ${p.name}${p.error ? ' (Error: ' + p.error + ')' : ''}`);
});
}
// Save detailed results
const fs = require('fs');
const outputPath = path.join(__dirname, '..', 'data', 'attribute-check-results.json');
fs.writeFileSync(outputPath, JSON.stringify(results, null, 2));
console.log(`\n💾 Detailed results saved to: ${outputPath}`);
return results;
}
// Run if called directly
if (require.main === module) {
if (!CONFIG.url || !CONFIG.key || !CONFIG.secret) {
console.error('❌ Missing WooCommerce credentials in environment variables');
process.exit(1);
}
checkProductAttributes()
.then(() => {
console.log('\n✅ Attribute check complete');
process.exit(0);
})
.catch(error => {
console.error('\n❌ Attribute check failed:', error.message);
process.exit(1);
});
}
module.exports = { checkProductAttributes };