Need to generate via script an Intercompany Sales ...
# suitescript
e
Need to generate via script an Intercompany Sales Order from a given Purchase Order. I am pretty close, but unable to save due to an interesting error:
Copy code
{
  "type": "error.SuiteScriptError",
  "name": "SSS_MISSING_REQD_ARGUMENT",
  "message": "line",
  "stack": [
    "nlapiCreateError(NLRecordScripting.scriptInit:1499)",
    "nsapiAssertTrue(NLRecordScripting.scriptInit:2326)",
    "nsapiCheckArgs(NLRecordScripting.scriptInit:2300)",
    "nlapiRemoveLineItem(NLRecordScripting.scriptInit:1844)",
    "removeAllItemLines(NLRecordScripting.scriptInit:8207)",
    "syncItemMachine(NLRecordScripting.scriptInit:8189)",
    "page_init(NLRecordScripting.scriptInit:8241)",
    "(N/record/recordService.js)",
    "onRequest(/SuiteScripts/.../testSL.js:58)"
  ],
  "cause": {
    "type": "internal error",
    "code": "SSS_MISSING_REQD_ARGUMENT",
    "details": "line",
    "userEvent": null,
    "stackTrace": [
      "nlapiCreateError(NLRecordScripting.scriptInit:1499)",
      "nsapiAssertTrue(NLRecordScripting.scriptInit:2326)",
      "nsapiCheckArgs(NLRecordScripting.scriptInit:2300)",
      "nlapiRemoveLineItem(NLRecordScripting.scriptInit:1844)",
      "removeAllItemLines(NLRecordScripting.scriptInit:8207)",
      "syncItemMachine(NLRecordScripting.scriptInit:8189)",
      "page_init(NLRecordScripting.scriptInit:8241)",
      "(N/record/recordService.js)",
      "onRequest(/SuiteScripts/.../testSL.js:58)"
    ],
    "notifyOff": false
  },
  "id": "",
  "notifyOff": false,
  "userFacing": false
}
Pasting code within thread because I know @battk will ask for it!
🤣 1
Copy code
/**
 * @NApiVersion 2.0
 * @NScriptType Suitelet
 * @NModuleScope Public
 */

define(['N/record'], function (record) {
    return { onRequest: onRequest };

    function onRequest() {
        log.debug('start', new Date());

        var REC = record.create({

            type: record.Type.SALES_ORDER,

            defaultValues: {

                ictran: 658260,
                entity: 5109,
                subsidiary: 32,
                currency: 1

            }
        });

        var pairedICPO = 658260;
        var fieldMapping = {
            entity: "5109",
            subsidiary: "32",
            location: "23",
            class: "1", //Brand
            department: "19", //Cost of Sales : Direct COGS
            currency: 1,
            //intercostatus: 2,
            //intercotransaction: 658260
        };

        var itemLines = {
            item: "6651",
            location: "23",
            quantity: "1",
            rate: "10.95",

        };

        util.each(fieldMapping, function (value, fieldId) {
            REC.setValue({ fieldId: fieldId, value: value });
        });

        log.debug('before', REC.getLineCount({ sublistId: 'item' }));
        util.each(itemLines, function (value, fieldId) {
            REC.setSublistValue({ fieldId: fieldId, value: value, sublistId: 'item', line: 0 });
        });
        log.debug('after', REC.getLineCount({ sublistId: 'item' }));

        var id = REC.save({ ignoreMandatoryFields: true, enableSourcing: false });

        log.debug(id);
    }
});
note: Item type is inventory (seemingly only non inventory is available for manual creation? Is this a truth?)
n
It kind of looks like its not this code that is erroring, but perhaps some other script. Something is trying to remove all line items and failing because there are no lines to remove.
Also it looks like maybe you are using a custom utility module that you are referencing with util.each that maybe isnt loaded in to your script?
Kind of a shot in the dark there though. The error is weird.
The error is SS 1 and you are using 2.0 which is why i think its not your script thats the problem
oh yeah. you didnt load in N/util in your define statement. For starters at least. TIL there is a util module in netsuite
e
you don’t need to load util, it’s inherent
and those SuiteScript 1.0 references are something internal to NS; for example, all ā€œNLā€ references…
what is interesting is that it seems to be loading something client side. i also notice when i run this in the Debugger that I get the following ā€œwarningā€ (which doesn’t occur in Suitelet, server side):
You changed the paired intercompany transaction associated with this transaction. Click OK to replace the items on this transaction with the items from the paired intercompany transaction. Click Cancel to add the items from the paired intercompany transaction to this transaction.
n
Ah gotcha. Kind of like log. neat In that case, maybe something with your default values when you are creating the record. I've had issues with that before. Otherwise im no help at all and will be leaving you alone now
e
thanks @Nathan L for all the help! still unsolved but much appreciated
b
you probably dont want to be setting any fields that you wouldnt in the ui
in this case that would be the currency, subsidiary, and entity
e
i’d love to set them in the ui too šŸ˜‰
b
and honestly any of those other body fields you set if they arent mandatory
e
so leave them off, and let it naturally populate?
b
otherwise, you dont want to
ignoreMandatoryFields
it could be hiding a more obvious missing field
otherwise
enableSourcing
may be an option you may want to try
but in general, you can only get the entity, subsidiary, and currency wrong
you already set them in the default values
e
so basically the opposite of what i’ve built … šŸ˜† I really only did that to get out of issues with salesrep and other fields. modified all of those fields, added salesrep (required in this environment), ignoreMandatory false and sourcing true, no cigar
same error
b
otherwise id start with a non inventory item first, you are basically Manually Creating a Paired Intercompany Sales Order
with the same limitations
ive seen code that can acutally create it with inventory items, but its not what i would start with
šŸ™ 1
e
you mean this limitation?
You can manually create a paired intercompany sales order *only* if the order does not contain an inventory item.
i’d love to see that code you are referring to… that’s what I’m trying to accomplish. Basically, if the bulk processor can do it, why can’t we accomplish this via script? We need more control over the process than what the bulk processor provides. for example, only certain POs should be released - but it’s a custom and not native control
b
the code you write is not the same as the bulk processes
its more similar to trying to do something via the ui
the bullk processes are likely not based on suitescript
e
obviously šŸ˜„ but i’d like it to accomplish the same. do you know how i can replicate for Inventory Items? that’s the need, here
b
while the ui is
e
understood
there is some sort of client side error we’re seeing, it’s odd… but like you said, the bulk processor is doing who-knows-what in the background
b
doesnt look client side to me
its not an error about any browser related globals
e
the call stack included page_init is eerily similar to pageInit
b
a large part of why client script and server script work similarly is that they share the same code
e
btu i guess not?
aha
b
your attempt actually uses the default values, which is the way the ui does it
your code essentially works for me, though as mentioned, you start on non inventory items first to avoid weirdness
Copy code
require(["N/record"], function (record) {
  var itemLines = {
    item: "5",
    quantity: "1",
    rate: "1",
  };

  var purchaseOrder = record.create({
    type: record.Type.PURCHASE_ORDER,
    defaultValues: {
      entity: "10",
    },
  });

  purchaseOrder.setValue({ fieldId: "location", value: "1" });

  util.each(itemLines, function (value, fieldId) {
    purchaseOrder.setSublistValue({
      fieldId: fieldId,
      value: value,
      sublistId: "item",
      line: 0,
    });
  });

  var purchaseOrderId = purchaseOrder.save();
  log.debug(purchaseOrderId);

  var salesOrder = record.create({
    type: record.Type.SALES_ORDER,
    defaultValues: {
      ictran: purchaseOrderId,
      entity: 9,
      subsidiary: 3,
      currency: 1,
    },
  });
  util.each(itemLines, function (value, fieldId) {
    salesOrder.setSublistValue({
      fieldId: fieldId,
      value: value,
      sublistId: "item",
      line: 0,
    });
  });

  var salesOrderId = salesOrder.save();

  log.debug(salesOrderId);
});
e
great! seems almost identical. except it is with non inventory items, I presume. Can you get this to work with inventory items? ā€œweirdnessā€
b
you should be trying to get it to work with non inventory items first
e
thanks - i’ll give it a shot
not working! I had to tweak only a bit, but it is not working (on the SO side; PO gets created). Let’s focus on the error - it seems like there is an internal call (obviously not found in the script) to
syncItemMachine
which seems like this is the source of the issue (or further down the line -
removeAllLines
, etc) somewhere along the ā€œlinesā€ it is missing a reference to a line number. It is a bit odd what is occurring behind the scenes because when I simply log the line count, it is 1 before I even set values on the line. Something funky is happening, but no I cannot even get the standard non inventory SO to generate here…
b
cant really debug that, so you are stuck with getting support involved
you will want to do the generic disabling all scripts/workflows deployed to the sales order before you do so
e
yes, thought crossed my mind. I think I shall! (disable scripts, that is - as opposed to reaching out to Support. Not sure I’ll get anywhere with that, as others told me their response was this is not supported/an enhancement)
but i of course will in due time, if necessary
thought just crossed my mind, since you mentioned disabling scripts - I see a Workflow referencing Sublist Action Groups… think I should disable those as well?
b
disabling the parent workflow will prevent all actions from running
e
yea, no cigar. tried disabling all UE, WF and even Client scripts. All undeployed, same error. redeploying now.
alright i’m going to have to resort to reaching out to support, but honestly i think i know what they are going to respond…
@battk OK, I got a non inventory SO created! Thanks for your help. Here’s the thing, I kept getting the cryptic error message about SSS_MISSING_REQD_ARGUMENT until I modified the script to not use
defaultValues
. Rather, I set them all via
setValue
calls. So, now when I try with Inventory PO => SO, I am stuck as I get failures when I attempt to not use the
defaultValues
parameter. Specifically, the intercotransaction cannot be set (much like in the UI); when I use
defaultValues
ONLY for the single parameter (
ictran
), I get a weird message that this item cannot be added to the order immediately on the
record.create
call.
i’m now getting a slightly different error, same error with a diff stack trace
Copy code
{
  "type": "error.SuiteScriptError",
  "name": "SSS_MISSING_REQD_ARGUMENT",
  "message": "line",
  "id": "",
  "stack": [
    "Error\n at RecordInvoker.save (suitescript/resources/javascript/record/serverRecordService.js:371:13)\n at NetSuiteObject.thenableFunction() (suitescript/resources/javascript/record/proxy.js:115:24)\n at Object.onRequest (/SuiteScripts/.../....js:112:39)"
  ],
  "cause": {
    "type": "internal error",
    "code": "SSS_MISSING_REQD_ARGUMENT",
    "details": "line",
    "userEvent": null,
    "stackTrace": [
      "Error\n at RecordInvoker.save (suitescript/resources/javascript/record/serverRecordService.js:371:13)\n at NetSuiteObject.thenableFunction() (suitescript/resources/javascript/record/proxy.js:115:24)\n at Object.onRequest (/SuiteScripts/.../....js:112:39)"
    ],
    "notifyOff": false
  },
  "notifyOff": false,
  "userFacing": true
}
b
you will probably only get the non inventory items working by using setValue for the ictran
the defaultValue version bypasses the validation that limits the fields to only pos that dont have inventory items
e
ok, but i get those weird errors - missing required argument, ā€œlineā€