Create PO Purchase Order in BOI c# on Sage 100


Hello, getting an error: Invalid or missing header on the code below- can anyone provide a working example of creating a purchase order in BOI? 

   using (var sySession = new MasSession(homePath))

                CI.ColumnNames.Add("PO_PURCHASEORDER_BUS", new Dictionary<string, string> { { CI.NextNumberMethod, "nGetNextPurchaseOrderNo" }, { CI.HeaderKeyColumns, "PurchaseOrderNo$" } });
                using (var poEntry = sySession.CreateObject<ILineEntry>("PO_PurchaseOrder_bus", "PO_PurchaseOrder_ui", "P/O"))

   var nextOrderNo = poEntry.GetNextDocumentNumber();

                    poEntry.SetKeyValue("PurchaseOrderNo", nextOrderNo);
                      poEntry.SetValue("PurchaseOrderDate", "20231101");
                      poEntry.SetValue("OrderType", "S");
                    poEntry.SetValue("APDivisionNo", "00");
                    poEntry.SetValue("VendorNo", "0008000");



                    poEntry.Lines.SetValue("ItemCode", "1001-HON-H252");
                    poEntry.Lines.SetValue("QuantityOrdered", 2);


  • 0

    Change your line "poEntry.SetKeyValue("PurchaseOrderNo", nextOrderNo);" to "poEntry.SetKey("PurchaseOrderNo", nextOrderNo);" and I believe it will work.  Generally, use SetKeyValue when you have multiple fields in the key to the table.  Then follow up with a SetKey().  When there is only 1 field in the key, just use SetKey(variable).

  • 0 in reply to Ray P

    I goofed up.  Change your line to:  poEntry.SetKey(nextOrderNo);

  • 0 in reply to Ray P

    When i try setkey (the way you mentioned above) Sage returns {"<Error: 88 in Method SETKEY>"}

  • 0 in reply to Anastasia Maher

    Are you sure that you're getting the next Purchase Order number?  The method in PO_PurchaseOrder_bus to get it is  GetNextPurchaseOrderNo(value$).  Try using var nextOrderNo = poEntry.GetNextPurchaseOrderNo();

  • 0 in reply to Ray P

    Yes we are using this in the code and using nextOrderNo

  • +1 in reply to Anastasia Maher
    verified answer

    Try updating your code as follows:

    var nextOrderNo = poEntry.nGetNextDocumentNumber();    <==  I don't see this command in the object reference for PO_PurchaseOrder_bus.  I think it will need to be changed to poEntry.nGetNextPurchaseOrderNo().  Just to get the code going why not hard code the PO number like you did for the date?

    poEntry.nSetValue("PurchaseOrderDate$", "20231101");
    poEntry.nSetValue("OrderType$", "S");
    poEntry.nSetValue("APDivisionNo$", "00");
    poEntry.nSetValue("VendorNo$", "0008000");



    poEntry.oLines.nSetValue("ItemCode$", "1001-HON-H252");
    poEntry.oLines.nSetValue("QuantityOrdered", 2);



    Fields that contain string values (including dates) must have the $ after the field name.  I also added "n" in front of all of your commands.  I don't program in c# so I'm no help on the syntax for it.  I think you need to refer to the lines object as oLines vs. Lines.  Here's some code from a script I did in vbscript:

    vCompany = "ABC"
    PathHome = "c:\sage\mas90\home"

    Set oScript = CreateObject("ProvideX.Script")
    oScript.Init (PathHome)

    Set oSS = oScript.NewObject("SY_SESSION")
    retVal = oSS.nlogon()

    If retVal = 0 Then
        User = "username"
        Password = "userpassword"
        retVal = oSS.nSetUser(User, Password)
    End If

    If retVal = 0 Then
        MsgBox (oSS.sLastErrorMsg & vbCrLf & "Quiting")
        Set oSS = Nothing
    End If

    retVal = oSS.nSetCompany(vCompanyTo)

    If retVal = 0 Then
        MsgBox (oSS.sLastErrorMsg & vbCrLf & "Quiting")
        Set oSS = Nothing
    End If

    vOrdDate = CStr(Year(objRS2(1))) & Right("00" & CStr(Month(objRS2(1))), 2) & Right("00" & CStr(Day(objRS2(1))), 2)

    If Not (IsObject(oPO)) Then
        retVal = oSS.nSetDate("P/O", vOrdDate)
        retVal = oSS.nSetModule("P/O")
        retVal = oSS.nSetProgram(oSS.nLookupTask("PO_PurchaseOrder_UI"))
        Set oPO = oScript.NewObject("PO_PurchaseOrder_bus", oSS)
    End If

    retVal = oPO.nGetNextPurchaseOrderNo(vPO)
    retVal = oPO.nSetKey(vPO)
    retVal = oPO.nSetValue("APDivisionNo$", "00")
    retVal = oPO.nSetValue("VendorNo$", vVend)
    retVal = oPO.nSetValue("PurchaseOrderDate$", vOrdDate)

    retVal = oPO.oLines.nAddLine()
    retVal = oPO.oLines.nSetValue("ItemCode$", vIC)
    retVal = oPO.oLines.nSetValue("ItemCodeDesc$", vICD)
    retVal = oPO.oLines.nSetValue("QuantityOrdered", vQO)
    retVal = oPO.oLines.nSetValue("CommentText$", vCmnt)
    retVal = oPO.oLines.nWrite()
    retVal = oPO.nWrite()

    I eliminated some of the loops and didn't define all of the variables but you should be able to see the syntax and the flow of the script from here.  I hope this is helpful.  Thanks.

  • 0 in reply to Ray P

    thank you so much!, i think there is definitely a custom script

  • 0 in reply to Anastasia Maher

    Hi   do you have an example for writing the Goods Receipt to Sage? A PO Goods Receipt - i am having trouble posting one, it posts in the batch but does not have any lines

  • 0 in reply to Anastasia Maher

    Here's a snippet of a process I made to set up Receipts of Goods for a whole PO at a time.  The source data is an Excel spreadsheet where only the PO number is entered.  The script brings in all lines on the PO and receives them in full.  I hope this helps.

    retVal = oROG.nGetNextReceiptNo(vReceiptNo)
    retVal = oROG.nSetKeyValue("ReceiptType$", "G")
    retVal = oROG.nSetKeyValue("ReceiptNo$", vReceiptNo)
    retVal = oROG.nSetKey()
    retVal = oROG.nSetValue("PurchaseOrderNo$", vPO)
    retVal = oROG.nApplyPurchaseOrderUpdate(vPO, "N", "Y", "N")
    retVal = oROG.nApplyPurchaseOrderCopyLines(vLinesCopied)

    If vInvoiceNo <> "" Then
    retVal = oROG.nSetValue("InvoiceNo$", vInvoiceNo)
    retVal = oROG.nSetValue("InvoiceDate$", vInvoiceDate)
    End If

    retVal = oROGLines.nWrite()
    retVal = oROG.nWrite()