Home > other >  Trying to use Sheets as db to update prices in WooCommerce
Trying to use Sheets as db to update prices in WooCommerce

Time:01-14

So I'm trying to use a single sheet as a price db to update prices in WooCommerce through the Woo API, using fetch. It works, my problem is that it apparently works depending on the size of the dataset? I'm not sure because I can't understand the error.

UPDATED CODE

function getDataloopwoo() {

    const ck = 'ck_fd0992917fbbb0464d4146ad5861f51adcb36369';
    const cs = 'cs_6f8061efce415355fb6cac520bd1506ad126578a';
    const website = 'https://www.atopems-desarrollo.com.ar';

    const optionsGet =
            {
                'method': 'GET',
                'contentType': 'application/x-www-form-urlencoded;charset=UTF-8',
                'muteHttpExceptions': true,
            };


    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
    const codigos = sheet.getRange('A2:A').getValues();
    const precios = sheet.getRange('B2:B').getValues();

    const data = codigos.map(function(codigos, indice) {
                return {
                    sku: codigos[0],
                    price: precios[indice][0]
                }
            })    
    const container = [];
    var surl = website   '/wp-json/wc/v3/products?consumer_key='   ck   '&consumer_secret='   cs   '&per_page=100'   '&orderby=id'   '&order=asc'   '&status=publish'   '&page=1';
    var url = surl
    Logger.log(url)



    var result = UrlFetchApp.fetch(url, optionsGet);
    var headers = result.getAllHeaders();
    var total_pages = 45;
    var pages_count = 0;
    while (pages_count < total_pages) {

        if (result.getResponseCode() == 200) {

            var wooProducts = JSON.parse(result.getContentText());
            //Logger.log(result.getContentText());
        }


        for (var i = 0; i < wooProducts.length; i  ) {
            //Logger.log(i);
            container.push({
                sku: wooProducts[i]['sku'],
                id: wooProducts[i]['id'],
                price: wooProducts[i]['price']
            });                        
        }
        pages_count  ;
        if (pages_count < total_pages) {
            var surl = website   '/wp-json/wc/v3/products?consumer_key='   ck   '&consumer_secret='   cs   '&per_page=100'   '&orderby=id'   '&order=asc'   '&status=publish'   '&page='   (pages_count   1);
            var url = surl
            var result = UrlFetchApp.fetch(url, optionsGet);
            Logger.log(url);

        }        
    }        
  
    var data_obj = {}
    for (let obj of data)
        data_obj[obj.sku] = {'price': obj.price};

    console.log(data_obj);
    
    var container_obj = {}
    for (let obj of container)
        container_obj[obj.sku] = {'price': obj.price, 'id': obj.id};
    
    console.log(container_obj);
    
    const output = [];
    for (let sku in container_obj) {
        let data_subObj = data_obj[sku];
        let container_subObj = container_obj[sku];
        if (data_subObj.price > container_subObj.price) {
            output.push({'id':container_subObj.id, 'regular_price':data_subObj.price});
        }          
    } 

    console.log(output);

    var temporary, chunk = 100;
    for (let i = 0;i < output.length; i  = chunk) {
        temporary = output.slice(i, i   chunk);
        var payloadUp = {
          update: temporary
        }
        var headPost = 
        {
          'method' : 'POST',
          'contentType': 'application/json',
          'payload': JSON.stringify(payloadUp)              
        };

        console.log(payloadUp);

        var urlPost = website   '/wp-json/wc/v3/products/batch?consumer_key='   ck   '&consumer_secret='   cs;
        var result = UrlFetchApp.fetch(urlPost, headPost);
        console.log(urlPost);
        if (result.getResponseCode() == 200) {
          console.log(result.getContentText());
        };
    } 
}

I use the var headers to get all headers but since I'm testing ATM I don't use it. So if I get around 15-20 products from WooCoommerce everything works like a charm, I get all product data, create a new array with sku, id and price. Then compare that array with an array from my sheets with the updated price value and then push sku, id and updated price to a new array and POST that array to woocommerce batch update. Works fine, if I try to process more I get this error:

TypeError: Cannot read property 'price' of undefined

I'm really wracking my brains mostly because I'm a total novice in JS.

I'll post the logs,

Logger.log(url);
https://atopems.com/wp-json/wc/v3/products?consumer_key=ck_xxx&consumer_secret=cs_xxx&per_page=100&orderby=id&order=asc&status=publish&page=51
console.log(data_obj);
Logging output too large. Truncating output. { '200': { price: 299.98 },
  '201': { price: 156.9 },
  '202': { price: 112.05 },
  '203': { price: 100.58 },
  '204': { price: 126.33 },
  '205': { price: 126.53 },
  '206': { price: 2858.42 },
  '207': { price: 2336.79 },
  '208': { price: 401.25 },
  '209': { price: 378.32 },
  '210': { price: 282.78 },
  '211': { price: 252.21 },
  '212': { price: 292.34 },
  '213': { price: 309.53 },
  '214': { price: 385.96 },
  '215': { price: 554.1 },
console.log(container_obj);
Logging output too large. Truncating output. { '60026': { price: '2319.6', id: 24942 },
  '60032': { price: '4050.7', id: 24943 },
  '60033': { price: '4050.7', id: 24944 },
  '60119': { price: '7195.72', id: 24945 },
  BR9010: { price: '984.5', id: 24067 },
  BR9013: { price: '1744.32', id: 24068 },
  BR9014: { price: '1869.03', id: 24069 },
  BR9015: { price: '1869.03', id: 24070 },
  BR9016: { price: '984.5', id: 24071 },
  BR9017: { price: '747.66', id: 24072 },
  BR9026: { price: '664.52', id: 24073 },
  BR9037: { price: '830.62', id: 24074 },
  BR9042: { price: '830.62', id: 24075 },
  BR9043: { price: '747.66', id: 24076 },
  BR9048: { price: '1204.44', id: 24077 },
  BR9049: { price: '955.23', id: 24078 },
  BR9050: { price: '955.23', id: 24079 },
  BR9052: { price: '1079.9', id: 24080 },
  BR9055: { price: '955.23', id: 24081 },
  BR9056: { price: '1266.63', id: 24082 },
  BR9059: { price: '955.23', id: 24083 },
  BR9067: { price: '830.62', id: 24084 },
  BR9068: { price: '1349.13', id: 24085 }

The exact error

17:07:38    Error   
TypeError: Cannot read property 'price' of undefined
getDataloopwoo  @ JSONsheet.gs:63

The sheet in question, in case anyone wants to see the type of data I'm working with.

const data = codigos.map etc

uses 2 variables, SKU and PRICE, which are column A and B respectively in the sheet as simple objects.

EDIT:

Ok, Test sheet that can be copied with CK and CS Keys to a testing WooCommerce site.

https://docs.google.com/spreadsheets/d/14afFyj1geaNCWt_e4DE9S41wlgepWAtasK2z5_u1hdc/edit?usp=sharing

If run as is it can be reproduced without doing anything else.

Tried with 20 pages it works, with 45 it doesn't.

I'm not sure what more I could do to make it reproducible.

  • I legit don't understand what could be the root of the problem.

CodePudding user response:

Modification points:

  • In your situation, it seems that the values of sku of container is not existing in the values of sku of data_obj. I thought that the reason for your issue might be due to this.
  • As a script for checking this, you can use const res = container.filter(e => !data_obj[e.sku]) for your script. In this case, [ { sku: 'L4943-0ULT', id: 3195, price: '5083.33' } ] is returned. When this value is searched from your sample Spreadsheet, l4943-0ult is found. In this case, the character case is different. By this, your issue occurs. I resulted in the reason of your issue is due to this.

When this issue was removed, how about the following modification?

From:

data_obj[obj.sku] = {'price': obj.price};

To:

data_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = {'price': obj.price};

And,

From:

container_obj[obj.sku] = {'price': obj.price, 'id': obj.id};

To:

container_obj[isNaN(obj.sku) ? obj.sku.toUpperCase() : obj.sku] = { 'price': obj.price, 'id': obj.id };

And also, in order to avoid no keys in the if statement, how about adding the following modification?

From:

if (data_subObj.price > container_subObj.price) {

To:

if (data_subObj && data_subObj.price > container_subObj.price) {
  •  Tags:  
  • Related