I've got a function here that's populating invento...
# suitescript
c
I've got a function here that's populating inventory detail on a Work Order Completion Component Inventory Detail Subrecord. When I save the Work Order Completion after this, it says that I need to configure inventory detail for line 1 which is what this is doing. Its like it doesn't like the values. I've manually entered the values I'm getting in this function into the UI and it works fine. I've tried internal ID of the serial/lot number as well as setText. I've also tried both 'receiptinventorynumber' and 'issueinventorynumber' for the lot number and it still fails either way. This code DOES work fine if i'm setting a header level inventory detail. The difference is the sublist inventory record has a sublist to choose the lot number from (the header level inventory detail is just a text field for this since you're creating the inventory). The completion quantity IS populated on the work order completion record (which drives the component counts) so its not that. Am I just doing something stupid I am not seeing?
Copy code
function populateInventoryDetail(dataIn) {

        var inventoryDetailSubrecord = dataIn.inventoryDetailSubrecord;

        const COMPLETION_QUANTITY = dataIn.completionQuantity;
        const LOT_NUMBER          = dataIn.lotNumber;
        const LOT_EXPIRATION_DATE = dataIn.lotExpirationDate;
        

        inventoryDetailSubrecord.selectNewLine({
            sublistId: 'inventoryassignment'
        });
        
        inventoryDetailSubrecord.setCurrentSublistValue({
            sublistId: 'inventoryassignment',
            fieldId: 'receiptinventorynumber', // also tried issueinventorynumber. receiptinventorynumber works fine for header level at least
            value: LOT_NUMBER
        });
       
        inventoryDetailSubrecord.setCurrentSublistValue({
            sublistId: 'inventoryassignment',
            fieldId: 'quantity',
            value: COMPLETION_QUANTITY
        });

        if (LOT_EXPIRATION_DATE) {
            inventoryDetailSubrecord.setCurrentSublistValue({
                sublistId: 'inventoryassignment',
                fieldId: 'expirationdate',
                value: LOT_EXPIRATION_DATE
            });
        }

        inventoryDetailSubrecord.commitLine({
            sublistId: 'inventoryassignment'
        });
    }
b
with all the data hiding, the only thing i can tell is that you use selectNewLine, in combination with setCurrentSublistValue and commitLine
which in general is a reasonable approach for setting sublist fields in dynamic records
if you want better help, leave code that i can run in a debugger to reproduce your problem
e
Are you setting the quantity and completed quantity first? I recall having trouble in dynamic mode with completions
c
Yes, completed quantity is set first as that drives it all.
Yeah the process works fine. For some reason, on a component inventory detail, it doesn't work the same way.
If i take a look at the sublist/subrecord contents right before the save (after the code above has run), its clearly configured. It has the right record ID for issueinventorynumber and the correct name for receiptinventorynumber
Copy code
"sublists": {
    "inventoryassignment": {
      "currentline": {
        "basequantityavailable": "",
        "binnumber": "",
        "binnumber_display": "",
        "existingexpdate": "",
        "existinginventorynumber": "",
        "expirationdate": "",
        "internalid": "-1",
        "inventorydetail": "-1",
        "inventorystatus": "",
        "inventorystatus_display": "",
        "issueinventorynumber": "",
        "lotquantityavailable": "",
        "numberedrecordid": "",
        "packcarton": "",
        "pickcarton": "",
        "quantity": "",
        "quantityavailable": "",
        "quantitystaged": "",
        "receiptinventorynumber": "",
        "sys_id": "-4480001405399394",
        "sys_parentid": "-4480001362440291",
        "tobinnumber": "",
        "tobinnumber_display": "",
        "toinventorystatus": "",
        "toinventorystatus_display": "",
        "totalquantityavailable": "",
        "#": "2"
      },
      "line 1": {
        "basequantityavailable": "1199999.33333332",
        "binnumber": "",
        "binnumber_display": "",
        "existingexpdate": "",
        "existinginventorynumber": "",
        "expirationdate": "1/11/2022",
        "internalid": "-1",
        "inventorydetail": "-1",
        "inventorystatus": "",
        "inventorystatus_display": "",
        "issueinventorynumber": "46",
        "lotquantityavailable": "",
        "numberedrecordid": "",
        "packcarton": "",
        "pickcarton": "",
        "quantity": "0.83333335",
        "quantityavailable": "1199999.33333332",
        "quantitystaged": "",
        "receiptinventorynumber": "TEST123",
        "sys_id": "-4480001392820301",
        "sys_parentid": "-4480001362440291",
        "tobinnumber": "",
        "tobinnumber_display": "",
        "toinventorystatus": "",
        "toinventorystatus_display": "",
        "totalquantityavailable": ""
      }
    }
b
this looks like it will be a pain to reproduce
1000000 1
are there uoms and is the assembly member also a lot item
c
Its just a super generic test lot assembly item. Yes, looks like it does have uoms. All of the values in the debug are OK to me. Im not doing anything special at all. Just getting the component inventory detail subrecord and running the method above which does in fact configure the inventory detail as seen in the json. If you do a work order completion w/ backflush its the same process. On save it should actually create the record and it just bombs and says its not configured.
I figured I was doing something dumb that I just wasn't seeing
So gonna try to do this non-dynamic
so if this is true, the LINE level inventory detail cannot be modified in dynamic mode. Header level can be modified.
b
Id try logging the inventory detail created in the ui to compare it to the one you are creating in script
Id also try doing it on a uom without fractional quantity to make sure its not a rounding issue
c
Yeah i did that w/ the UI it has the same values
its gotta be the dynamic mode but itll take me a few to test
a
@creece Are you committing the line after you commit the inventory detail line?
b
i ignored the uom aspect of the answer since i didnt really want to fiddle around with numbers
otherwise dynamic mode works
i made the modification of using issueinventorynumber and a proper internal id for the lot
in general, use issueinventorynumber when your inventory decreases and receiptinventorynumber when your inventory increases
Copy code
require(["N/record"], function (record) {
  var workOrder = record.create({ type: "workorder" });
  workOrder.setValue({ fieldId: "subsidiary", value: "1" });
  workOrder.setValue({ fieldId: "location", value: "1" });
  workOrder.setValue({ fieldId: "assemblyitem", value: "262" });
  workOrder.setValue({ fieldId: "iswip", value: true });
  workOrder.setValue({ fieldId: "quantity", value: 1 });
  var workOrderId = workOrder.save();

  var workOrderCompletion = record.transform({
    fromType: "workorder",
    fromId: workOrderId,
    toType: "workordercompletion",
    isDynamic: true,
    defaultValues: { isbackflush: true },
  });
  workOrderCompletion.setValue({ fieldId: "quantity", value: 1 });

  workOrderCompletion.selectLine({ sublistId: "component", line: 0 });

  var componentInventoryDetail = workOrderCompletion.getCurrentSublistSubrecord(
    { sublistId: "component", fieldId: "componentinventorydetail" }
  );
  componentInventoryDetail.selectNewLine({ sublistId: "inventoryassignment" });
  componentInventoryDetail.setCurrentSublistValue({
    sublistId: "inventoryassignment",
    fieldId: "issueinventorynumber",
    value: "115",
  });
  componentInventoryDetail.setCurrentSublistValue({
    sublistId: "inventoryassignment",
    fieldId: "quantity",
    value: 1,
  });
  componentInventoryDetail.commitLine({ sublistId: "inventoryassignment" });

  workOrderCompletion.commitLine({ sublistId: "component" });

  var assemblyItemInventoryDetail = workOrderCompletion.getSubrecord({
    fieldId: "inventorydetail",
  });
  assemblyItemInventoryDetail.selectNewLine({
    sublistId: "inventoryassignment",
  });
  assemblyItemInventoryDetail.setCurrentSublistValue({
    sublistId: "inventoryassignment",
    fieldId: "receiptinventorynumber",
    value: "Lot 1",
  });
  assemblyItemInventoryDetail.setCurrentSublistValue({
    sublistId: "inventoryassignment",
    fieldId: "quantity",
    value: 1,
  });
  assemblyItemInventoryDetail.commitLine({ sublistId: "inventoryassignment" });

  workOrderCompletion.save();
});
this code is ugly enough to warrant functions, i dont generally bother with that for code i share here
if you share how your assemblies and components setup and the uoms involved, i could try with those items
c
I was missing the commit line of the component
ill take my box of shame now
Thank you. I knew it was something stupid I did.
1 token for me
👍 1
a
@creece If make you feel better I spot it because happened too many times to me... hahaha
c
manufacturing side is pretty new to me so im still learning on that end
s
did you ever confirm if this worked in standard mode? IMHO the dynamic mode API is more obtuse (case in point - forgetting to call commit) and prefer to do things in standard mode unless forced otherwise
c
No, I did not check if it worked in standard mode as it works fine now in dynamic (and I needed dynamic for some fields). It should work in either mode
n
this has been worth it for me for battk statement "use issueinventorynumber when your inventory decreases and receiptinventorynumber when your inventory increases"
s
FWIW, with NFT only record types that have issueinventorynumber have it, and same for receiptinventorynumber
c
Not sure I got what you're saying @stalbert sorry
s
wait, I misinterpreted things. Though now you have my thinking about how to make InventoryDetail type aware of included types like itemreceipt and so forth
c
If you're assigning inventory like a components list, you use the issueinventory number. If you're creating inventory detail (like header level inventory detail) then use the receipt one. Thats how it works for me.
it makes you use the right one as far as I can tell so I dont think you need to worry
s
it would be nice if it gave you an error if you used the wrong field name