English 中文(简体)
Suitescript 2.0: Map Reduce script not creating a transaction
原标题:

EDIT: Working Version of Script included

I have the following map reduce script which is working as expected until it gets to the reduce stage.


    **
     *@NApiVersion 2.x
     *@NScriptType MapReduceScript
     */
    define(["N/search", "N/record"], function (search, record) {
      function getInputData() {
        var salesorderSearchObj = search.create({
          type: "salesorder",
          filters: [
            ["type", "anyof", "SalesOrd"],
            "AND",
            ["mainline", "is", "F"],
            "AND",
            ["taxline", "is", "F"],
            "AND",
            ["shipping", "is", "F"],
            "AND",
            ["item", "noneof", "@NONE@"],
            "AND",
            ["status", "anyof", "SalesOrd:F"],
          ],
          columns: [
            search.createColumn({ name: "tranid", label: "Document Number" }),
            search.createColumn({ name: "entity", label: "Name" }),
            search.createColumn({ name: "item", label: "Item" }),
            search.createColumn({ name: "rate", label: "Item Rate" }),
            search.createColumn({ name: "quantity", label: "Quantity" }),
            search.createColumn({ name: "amount", label: "Amount" }),
            search.createColumn({ name: "taxamount", label: "Amount (Tax)" }),
            search.createColumn({ name: "grossamount", label: "Amount (Gross)" }),
            search.createColumn({ name: "taxcode", label: "Tax Item" }),
            search.createColumn({ name: "memo", label: "Memo" }),
            search.createColumn({
              name: "lineuniquekey",
              label: "Line Unique Key",
            }),
          ],
        });
        return salesorderSearchObj;
      }
      /**
       * @param {MapReduceContext.map} context
       */
      function map(context) {
        var result = JSON.parse(context.value);
        log.debug("result", result);
    const entityValue = result.values.entity.value;
        const itemValue = result.values.item.value;
        const quantityValue = result.values.quantity;
        const rateValue = result.values.rate;
        const taxValue = result.values.taxamount;
        const amountValue = result.values.amount;
        const taxcodeValue = result.values.taxcode.value;
    
        // Create an object to hold item attributes
        const itemObj = {
          item: itemValue,
          quantity: quantityValue,
          rate: rateValue,
          amount: amountValue,
          taxamount: taxValue,
          taxcode: taxcodeValue,
        };
    
        // Group items by entity using entityValue as the key
        const entityItems = {}; //create an empty associative array
     if (entityValue in entityItems) {
          entityItems[entityValue].push(itemObj);
        } else {
          entityItems[entityValue] = [itemObj]; //otherwise, create a new key value pair of key (entityvalue) and value (itemObj)
        }
    
        context.write({
          key: entityValue,
          value: JSON.stringify(entityItems),
        });
        log.debug("map context debug", context);
      }
      /**
       * @param {MapReduceContext.reduce} context
       */
      function reduce(context) {
        log.debug("reduce context", context);
    
        var values = context.values;
        log.debug("context.values", values);
        var entity = context.key;
        log.debug("context.key", entity);
    
        log.debug("values.length", values.length)
    for (var i = 0; i < values.length; i++) {
     var jsonStr = values[i];
      log.debug("jsonstr", jsonStr);
          var entityData = JSON.parse(jsonStr);
          var salesOrderRec = record.create({
            type: record.Type.SALES_ORDER,
            isDynamic: true,
          });
    
          log.debug({
            title: "salesOrderRec",
            details: salesOrderRec,
          });
          for (var entity in entityData) {
            if (entityData.hasOwnProperty(entity)) {
     var items = entityData[entity];
              for (var j = 0; j < items.length; j++) {
                var itemData = items[j];
    
                // Access individual values and set them as variables
                var item = itemData.item;
                var quantity = itemData.quantity;
                var rate = itemData.rate;
                var amount = itemData.amount;
                var taxamount = itemData.taxamount;
                var taxcode = itemData.taxcode;
    
                log.debug("item:", item);
                log.debug("quantity:", quantity);
                log.debug("rate:", rate);
                log.debug("amount:", amount);
                log.debug("taxamt:", taxamount);
    
                salesOrderRec.setValue({
                  fieldId: "entity",
                  value: entity, // set customer ID here
                });
    
                salesOrder.selectNewLine({
                  sublistId: "item",
                });
    
                salesOrder.setCurrentSublistValue({
                  sublistId: "item",
                  fieldId: "item",
                  value: item,
                });
    
                salesOrder.setCurrentSublistValue({
                  sublistId: "item",
                  fieldId: "quantity",
                  value: quantity,
                });
    
                //repeat above pattern to set the rest of the line fields
    
                salesOrderRec.commitLine({
                  sublistId: "item",
                });
              }
            }
          }
    
          // Save the sales order record after all items have been added
          var salesOrderId = salesOrderRec.save();
    
          if (salesOrderId) {
            log.debug("Sales Order ID", salesOrderId);
          } else {
            log.debug("Failed to create Sales Order");
          }
        }
        var salesOrderId = salesOrderRec.save();
        log.debug("Sales Order ID", salesOrderId);
      }
    
      /**
       * @param {MapReduceContext.summarize} context
       */
      function summarize(summary) {}
      return {
        getInputData: getInputData,
        map: map,
        reduce: reduce,
        summarize: summarize,
      };
    });

The log debugs work until

 var salesOrderId = salesOrderRec.save();
    
          if (salesOrderId) {
            log.debug("Sales Order ID", salesOrderId);
          } else {
            log.debug("Failed to create Sales Order");
          }
        }
        var salesOrderId = salesOrderRec.save();
        log.debug("Sales Order ID", salesOrderId);
      }

This does not log anything. There are no error messages either. I have tried different variations of this code including moving the sales order record save to within the loop though can t see why this is not working.

Can anyone see where I am going wrong?

Thanks

EDIT: Working Version of Script:

/**
 * @NApiVersion 2.x
 * @NScriptType MapReduceScript
 */
define(["N/search", "N/record"], function (search, record) {
  function getInputData() {
    var invoiceSearchObj = search.create({
      type: "invoice",
      filters: [
        ["type", "anyof", "CustInvc"],
        "AND",
        ["mainline", "is", "F"],
        "AND",
        ["taxline", "is", "F"],
        "AND",
        ["item", "noneof", "@NONE@"],
        "AND",
        ["item.revenuerecognitionrule", "anyof", "@NONE@"],
        "AND",
        ["currency", "anyof", "5"],
        "AND",
        ["datecreated", "within", "thisfiscalquarter"],
      ],
      columns: [
        search.createColumn({
          name: "internalid",
          join: "customerMain",
          label: "Customer (Main Line) : Internal ID",
        }),
        search.createColumn({ name: "entity", label: "Name" }),
        search.createColumn({ name: "tranid", label: "Document Number" }),
        search.createColumn({ name: "item", label: "Item" }),
        search.createColumn({ name: "trandate", label: "Date" }),
        search.createColumn({ name: "amount", label: "Amount" }),
        search.createColumn({ name: "taxamount", label: "Amount (Tax)" }),
        search.createColumn({ name: "rate", label: "Item Rate" }),
        search.createColumn({ name: "quantity", label: "Quantity" }),
        search.createColumn({ name: "pricelevel", label: "Price Level" }),
        search.createColumn({ name: "taxcode", label: "Tax Item" }),
      ],
    });
    return invoiceSearchObj;
  }

  function map(context) {
    var result = JSON.parse(context.value);
    log.debug("result", result);

    const entityValue = result.values.entity.value;
    const itemValue = result.values.item.value;
    const quantityValue = result.values.quantity;
    const rateValue = result.values.rate;
    const taxValue = result.values.taxamount;
    const amountValue = result.values.amount;
    const taxcodeValue = result.values.taxcode.value;

    const itemObj = {
      item: itemValue,
      quantity: quantityValue,
      rate: rateValue,
      amount: amountValue,
      taxamount: taxValue,
      taxcode: taxcodeValue,
    };

    const entityItems = {};

    if (entityValue in entityItems) {
      entityItems[entityValue].push(itemObj);
    } else {
      entityItems[entityValue] = [itemObj];
    }

    context.write({
      key: entityValue,
      value: JSON.stringify(entityItems),
    });
    log.debug("map context debug", context);
  }

function reduce(context) {
  log.debug("reduce context", context);

  var values = context.values;
  log.debug("context.values", values);
  var entity = context.key;
  log.debug("context.key", entity);

  var salesOrderRec; // Declare salesOrderRec outside the loop

  for (var i = 0; i < values.length; i++) {
    var jsonStr = values[i];
    log.debug("jsonstr", jsonStr);
    var entityData = JSON.parse(jsonStr);

    for (var entity in entityData) {
      if (entityData.hasOwnProperty(entity)) {
        var items = entityData[entity];
        for (var j = 0; j < items.length; j++) {
          var itemData = items[j];

          // Access individual values and set them as variables
          var item = itemData.item;
          var quantity = itemData.quantity;
          var rate = itemData.rate;
          var amount = itemData.amount;
          var taxamount = itemData.taxamount;
          var taxcode = itemData.taxcode;

          log.debug("item:", item);
          log.debug("quantity:", quantity);
          log.debug("rate:", rate);
          log.debug("amount:", amount);
          log.debug("taxamt:", taxamount);

          try {
            if (!salesOrderRec) {
              salesOrderRec = record.create({
                type: record.Type.SALES_ORDER,
                isDynamic: true,
              });
              salesOrderRec.setValue({
                fieldId: "entity",
                value: entity, // set customer ID here
              });
              salesOrderRec.setValue({
                fieldId: "memo",
                value: JSON.stringify(item),
              });
            }

            salesOrderRec.selectNewLine({
              sublistId: "item",
            });

            salesOrderRec.setCurrentSublistValue({
              sublistId: "item",
              fieldId: "item",
              value: item,
            });

            salesOrderRec.setCurrentSublistValue({
              sublistId: "item",
              fieldId: "quantity",
              value: quantity,
            });

            // Set the rest of the line fields here

            salesOrderRec.commitLine({
              sublistId: "item",
            });
          } catch (e) {
            log.error({
              title: "Error creating sales order: ",
              details: e.message,
            });
          }
        }
      }
    }
  }

  if (salesOrderRec) {
    var salesOrderId = salesOrderRec.save();
    if (salesOrderId) {
      log.debug("Sales Order ID", salesOrderId);
    } else {
      log.debug("Failed to create Sales Order");
    }
  }
}

  return {
    getInputData: getInputData,
    map: map,
    reduce: reduce,
  };
});
最佳回答

Not sure if this is an answer, but to see uncaught errors from a Map/Reduce script, you have to iterate the errors passed to the summary function. for example:

function summarize(summary) {
    log.debug({
        title:  Summary ,
        details: summary
    });
    summary.reduceSummary.errors.iterator().each(function (key, error) {
        log.error( Reduce Error for key:   + key, error);
        return true;
    });
}

Once you re successfully logging the errors, I think the cause of your issue may become obvious.

问题回答

To return an error with Map/reduce script, you need to add a try/catch

Wrap the code in try catch and log the error .

While using MAP/REDUCE script you need to return the data at the end of your getInputData() entry point like :-

return {
        type:  search ,
        id:  data 
    };




相关问题
How to create a shopping cart(Ecommerce site) using NetSuite

I am new to NetSuite. I don t know anything about the NetSuite. I want to create a new Shoppping cart(Ecommerce site) in the NetSuite. I am not able to find the steps so that I can create a new ...

invalid argument IE7 javascript line number changes

This is the test page: http://www.onebagoneearth.com/ OBOEKindBag (spaces between the page name and domain because I don t want the URL indexed as such) If you click on one of the thumbnails, or ...

热门标签